)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"libvirt: fix detach volume race condition"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When a volume is detached, the according the share file is"},{"line_number":10,"context_line":"detached if no longer used. This can cause issues if at the same"},{"line_number":11,"context_line":"time, a different volume stored on the same share is being"},{"line_number":12,"context_line":"attached as the according disk image will not be available."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"bab6814e_3cd48cea","line":9,"range":{"start_line":9,"start_character":40,"end_line":9,"end_character":44},"updated":"2016-05-20 12:10:46.000000000","message":"I think you don\u0027t what that \"the\"","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":5406,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)"},{"line_number":5407,"context_line":""},{"line_number":5408,"context_line":"        devices \u003d drvr._get_all_file_devices()"},{"line_number":5409,"context_line":"        self.assertEqual(devices, [\u0027filename1\u0027, \u0027filename2\u0027, \u0027filename3\u0027])"},{"line_number":5410,"context_line":"        mock_list.assert_called_with(only_guests\u003dTrue, only_running\u003dTrue)"},{"line_number":5411,"context_line":""},{"line_number":5412,"context_line":"    @mock.patch(\u0027nova.virt.libvirt.host.Host.get_online_cpus\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_4cb21a07","line":5409,"updated":"2016-04-29 13:22:10.000000000","message":"assertEqual calls should be of the form assertEqual(expected, actual)","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":15674,"context_line":"        drv \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)"},{"line_number":15675,"context_line":"        mock_get_devices.return_value \u003d \\"},{"line_number":15676,"context_line":"            [\u0027/mnt/7238ca227f24b2984e2f10233a9c78a3/volume1\u0027,"},{"line_number":15677,"context_line":"             \u0027/mnt/7393bd3fad43865503de14402bb43dd2/volume2\u0027]"},{"line_number":15678,"context_line":"        expected_keys \u003d [\u0027/mnt/7238ca227f24b2984e2f10233a9c78a3\u0027,"},{"line_number":15679,"context_line":"                         \u0027/mnt/7393bd3fad43865503de14402bb43dd2\u0027]"},{"line_number":15680,"context_line":"        expected_values \u003d [[\u0027volume1\u0027], [\u0027volume2\u0027]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_4c0dfae6","line":15677,"updated":"2016-04-29 13:22:10.000000000","message":"I believe you can avoid using \\ here by:\n\nmock_get_devices.return_value \u003d [\n    \u0027/mnt/7238ca227f24b2984e2f10233a9c78a3/volume1\u0027,\n    \u0027/mnt/7393bd3fad43865503de14402bb43dd2/volume2\u0027\n]","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"b669159472b08a5a0ee4c7a09abec9ca8a372bee","unresolved":false,"context_lines":[{"line_number":15674,"context_line":"        drv \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)"},{"line_number":15675,"context_line":"        mock_get_devices.return_value \u003d \\"},{"line_number":15676,"context_line":"            [\u0027/mnt/7238ca227f24b2984e2f10233a9c78a3/volume1\u0027,"},{"line_number":15677,"context_line":"             \u0027/mnt/7393bd3fad43865503de14402bb43dd2/volume2\u0027]"},{"line_number":15678,"context_line":"        expected_keys \u003d [\u0027/mnt/7238ca227f24b2984e2f10233a9c78a3\u0027,"},{"line_number":15679,"context_line":"                         \u0027/mnt/7393bd3fad43865503de14402bb43dd2\u0027]"},{"line_number":15680,"context_line":"        expected_values \u003d [[\u0027volume1\u0027], [\u0027volume2\u0027]]"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_726b2886","line":15677,"in_reply_to":"1a122d0e_4c0dfae6","updated":"2016-05-03 07:57:46.000000000","message":"Done","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":15682,"context_line":"        drv._init_mount_path_usage()"},{"line_number":15683,"context_line":""},{"line_number":15684,"context_line":"        self.assertItemsEqual(expected_keys,"},{"line_number":15685,"context_line":"                        volume_fs.mount_path_usage.keys())"},{"line_number":15686,"context_line":""},{"line_number":15687,"context_line":"        self.assertItemsEqual(expected_values,"},{"line_number":15688,"context_line":"                        volume_fs.mount_path_usage.values())"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_4ce5fad9","line":15685,"updated":"2016-04-29 13:22:10.000000000","message":"This is a strange indent. Consider changing.","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"b669159472b08a5a0ee4c7a09abec9ca8a372bee","unresolved":false,"context_lines":[{"line_number":15682,"context_line":"        drv._init_mount_path_usage()"},{"line_number":15683,"context_line":""},{"line_number":15684,"context_line":"        self.assertItemsEqual(expected_keys,"},{"line_number":15685,"context_line":"                        volume_fs.mount_path_usage.keys())"},{"line_number":15686,"context_line":""},{"line_number":15687,"context_line":"        self.assertItemsEqual(expected_values,"},{"line_number":15688,"context_line":"                        volume_fs.mount_path_usage.values())"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_5268ac87","line":15685,"in_reply_to":"1a122d0e_4ce5fad9","updated":"2016-05-03 07:57:46.000000000","message":"Done","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":15685,"context_line":"                        volume_fs.mount_path_usage.keys())"},{"line_number":15686,"context_line":""},{"line_number":15687,"context_line":"        self.assertItemsEqual(expected_values,"},{"line_number":15688,"context_line":"                        volume_fs.mount_path_usage.values())"},{"line_number":15689,"context_line":""},{"line_number":15690,"context_line":""},{"line_number":15691,"context_line":"class LibvirtVolumeUsageTestCase(test.NoDBTestCase):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_2ce87eb2","line":15688,"updated":"2016-04-29 13:22:10.000000000","message":"Same here.","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"b669159472b08a5a0ee4c7a09abec9ca8a372bee","unresolved":false,"context_lines":[{"line_number":15685,"context_line":"                        volume_fs.mount_path_usage.keys())"},{"line_number":15686,"context_line":""},{"line_number":15687,"context_line":"        self.assertItemsEqual(expected_values,"},{"line_number":15688,"context_line":"                        volume_fs.mount_path_usage.values())"},{"line_number":15689,"context_line":""},{"line_number":15690,"context_line":""},{"line_number":15691,"context_line":"class LibvirtVolumeUsageTestCase(test.NoDBTestCase):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_920884db","line":15688,"in_reply_to":"1a122d0e_2ce87eb2","updated":"2016-05-03 07:57:46.000000000","message":"Done","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"}],"nova/tests/unit/virt/libvirt/volume/test_fs.py":[{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def test_update_mount_path_usage_connected(self):"},{"line_number":61,"context_line":"        self.driver.update_mount_path_usage(mock.sentinel.mount_path,"},{"line_number":62,"context_line":"                                            mock.sentinel.resurce)"},{"line_number":63,"context_line":"        self.assertEqual([mock.sentinel.resurce],"},{"line_number":64,"context_line":"                         fs.mount_path_usage[mock.sentinel.mount_path])"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_d25a8729","line":62,"range":{"start_line":62,"start_character":58,"end_line":62,"end_character":65},"updated":"2016-05-20 12:10:46.000000000","message":"nit: resource","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    def test_update_mount_path_usage_connected(self):"},{"line_number":61,"context_line":"        self.driver.update_mount_path_usage(mock.sentinel.mount_path,"},{"line_number":62,"context_line":"                                            mock.sentinel.resurce)"},{"line_number":63,"context_line":"        self.assertEqual([mock.sentinel.resurce],"},{"line_number":64,"context_line":"                         fs.mount_path_usage[mock.sentinel.mount_path])"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def test_update_mount_path_usage_disconnected(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_724abb56","line":63,"range":{"start_line":63,"start_character":40,"end_line":63,"end_character":47},"updated":"2016-05-20 12:10:46.000000000","message":"nit: resource","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def test_update_mount_path_usage_disconnected(self):"},{"line_number":67,"context_line":"        fs.mount_path_usage[mock.sentinel.mount_path] \u003d ["},{"line_number":68,"context_line":"            mock.sentinel.resurce]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        self.driver.update_mount_path_usage(mock.sentinel.mount_path,"},{"line_number":71,"context_line":"                                            mock.sentinel.resurce,"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_d271e7a9","line":68,"range":{"start_line":68,"start_character":26,"end_line":68,"end_character":33},"updated":"2016-05-20 12:10:46.000000000","message":"nit: resource","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":68,"context_line":"            mock.sentinel.resurce]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        self.driver.update_mount_path_usage(mock.sentinel.mount_path,"},{"line_number":71,"context_line":"                                            mock.sentinel.resurce,"},{"line_number":72,"context_line":"                                            connected\u003dFalse)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        self.assertNotIn([mock.sentinel.mount_path],"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_b29d43be","line":71,"range":{"start_line":71,"start_character":58,"end_line":71,"end_character":65},"updated":"2016-05-20 12:10:46.000000000","message":"nit: resource","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"}],"nova/tests/unit/virt/libvirt/volume/test_glusterfs.py":[{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":171,"context_line":"    @mock.patch.object(libvirt_utils, \u0027is_mounted\u0027)"},{"line_number":172,"context_line":"    @mock.patch.object(glusterfs.LibvirtGlusterfsVolumeDriver,"},{"line_number":173,"context_line":"                       \u0027is_mount_path_in_use\u0027)"},{"line_number":174,"context_line":"    def test_libvirt_nfs_driver_disconnect_share_in_use(self, mock_in_use,"},{"line_number":175,"context_line":"                                                          mock_is_mounted):"},{"line_number":176,"context_line":"        mock_is_mounted.return_value \u003d True"},{"line_number":177,"context_line":"        mock_in_use.return_value \u003d True"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_4c421a69","line":174,"updated":"2016-04-29 13:22:10.000000000","message":"I think perhaps you forgot to change the name of this test. Should it be: \u0027test_libvirt_glusterfs_driver_disconnect_share_in_use\u0027?","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"b669159472b08a5a0ee4c7a09abec9ca8a372bee","unresolved":false,"context_lines":[{"line_number":171,"context_line":"    @mock.patch.object(libvirt_utils, \u0027is_mounted\u0027)"},{"line_number":172,"context_line":"    @mock.patch.object(glusterfs.LibvirtGlusterfsVolumeDriver,"},{"line_number":173,"context_line":"                       \u0027is_mount_path_in_use\u0027)"},{"line_number":174,"context_line":"    def test_libvirt_nfs_driver_disconnect_share_in_use(self, mock_in_use,"},{"line_number":175,"context_line":"                                                          mock_is_mounted):"},{"line_number":176,"context_line":"        mock_is_mounted.return_value \u003d True"},{"line_number":177,"context_line":"        mock_in_use.return_value \u003d True"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_32f890c4","line":174,"in_reply_to":"1a122d0e_4c421a69","updated":"2016-05-03 07:57:46.000000000","message":"Yes, it is, Thanks","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":178,"context_line":""},{"line_number":179,"context_line":"        libvirt_driver \u003d glusterfs.LibvirtGlusterfsVolumeDriver(self.fake_conn)"},{"line_number":180,"context_line":"        connection_info \u003d {\u0027data\u0027: {\u0027export\u0027: \u0027192.168.1.1:/volume-00001\u0027,"},{"line_number":181,"context_line":"                                    \u0027name\u0027: self.name}}"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"        libvirt_driver.disconnect_volume(connection_info, \"vde\")"},{"line_number":184,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_cc910af3","line":181,"updated":"2016-04-29 13:22:10.000000000","message":"There\u0027s a nicer way of writing nested dicts. For example:\n\nconnection_info \u003d {\n    \u0027data\u0027: {\n       \u0027export\u0027: \u0027192.168.1.1:/volume-00001\u0027,\n       \u0027name\u0027: self.name\n    }\n}","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"}],"nova/tests/unit/virt/libvirt/volume/test_nfs.py":[{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        libvirt_driver \u003d nfs.LibvirtNFSVolumeDriver(self.fake_conn)"},{"line_number":139,"context_line":"        connection_info \u003d {\u0027data\u0027: {\u0027export\u0027: \u0027192.168.1.1:/nfs/share1\u0027,"},{"line_number":140,"context_line":"                                    \u0027name\u0027: self.name}}"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"        libvirt_driver.disconnect_volume(connection_info, \"vde\")"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_6c2276ba","line":140,"updated":"2016-04-29 13:22:10.000000000","message":"Same nested dict issue.","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"}],"nova/tests/unit/virt/libvirt/volume/test_smbfs.py":[{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"        libvirt_driver \u003d smbfs.LibvirtSMBFSVolumeDriver(self.fake_conn)"},{"line_number":66,"context_line":"        connection_info \u003d {\u0027data\u0027: {\u0027export\u0027: \u0027//192.168.1.1/volumes\u0027,"},{"line_number":67,"context_line":"                                    \u0027name\u0027: self.name}}"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        libvirt_driver.disconnect_volume(connection_info, \"vde\")"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_2721b99e","line":67,"updated":"2016-04-29 13:22:10.000000000","message":"Same nested dict issue.","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":704,"context_line":""},{"line_number":705,"context_line":"        self._init_mount_path_usage()"},{"line_number":706,"context_line":""},{"line_number":707,"context_line":"    def _init_mount_path_usage(self):"},{"line_number":708,"context_line":"        \"\"\"Initialize mount_path_usage with volumes already mounted\"\"\""},{"line_number":709,"context_line":"        devices \u003d self._get_all_file_devices()"},{"line_number":710,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_c7dbee4d","line":707,"range":{"start_line":707,"start_character":4,"end_line":707,"end_character":37},"updated":"2016-05-20 12:10:46.000000000","message":"minor: please can you move the definition of the method before we use it?","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":711,"context_line":"        for device in devices:"},{"line_number":712,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":713,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":714,"context_line":""},{"line_number":715,"context_line":"    def _get_all_file_devices(self):"},{"line_number":716,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":717,"context_line":"        devices \u003d []"},{"line_number":718,"context_line":"        for guest in self._host.list_guests():"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_27ed9aef","line":715,"range":{"start_line":714,"start_character":0,"end_line":715,"end_character":36},"updated":"2016-05-20 12:10:46.000000000","message":"minor: same as above","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"9688b6dfb745f277dea1c5c8c28e9140a0c0cb94","unresolved":false,"context_lines":[{"line_number":637,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":638,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    def _get_all_file_devices(self):"},{"line_number":641,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":642,"context_line":"        devices \u003d []"},{"line_number":643,"context_line":"        for guest in self._host.list_guests():"}],"source_content_type":"text/x-python","patch_set":8,"id":"bab6814e_6426abbb","line":640,"range":{"start_line":640,"start_character":1,"end_line":640,"end_character":36},"updated":"2016-05-25 13:41:01.000000000","message":"minor: that should go before the _init_mount_path_usage as it is called there for the first time","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f4fd562a1d9cb2a2d900c3e5b5c893e9849f64a3","unresolved":false,"context_lines":[{"line_number":637,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":638,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    def _get_all_file_devices(self):"},{"line_number":641,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":642,"context_line":"        devices \u003d []"},{"line_number":643,"context_line":"        for guest in self._host.list_guests():"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_cc43e36a","line":640,"range":{"start_line":640,"start_character":1,"end_line":640,"end_character":36},"in_reply_to":"9abb7d3a_9b69c18e","updated":"2016-06-01 12:28:48.000000000","message":"@Dan, thanks","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6720b5fd04568f05fa5130ec7f815df1ae34b56a","unresolved":false,"context_lines":[{"line_number":637,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":638,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    def _get_all_file_devices(self):"},{"line_number":641,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":642,"context_line":"        devices \u003d []"},{"line_number":643,"context_line":"        for guest in self._host.list_guests():"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_9b69c18e","line":640,"range":{"start_line":640,"start_character":1,"end_line":640,"end_character":36},"in_reply_to":"bab6814e_6426abbb","updated":"2016-05-27 16:25:41.000000000","message":"Agree.","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f4fd562a1d9cb2a2d900c3e5b5c893e9849f64a3","unresolved":false,"context_lines":[{"line_number":637,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":638,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    def _get_all_file_devices(self):"},{"line_number":641,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":642,"context_line":"        devices \u003d []"},{"line_number":643,"context_line":"        for guest in self._host.list_guests():"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_ac6f7ffa","line":640,"range":{"start_line":640,"start_character":1,"end_line":640,"end_character":36},"in_reply_to":"bab6814e_6426abbb","updated":"2016-06-01 12:28:48.000000000","message":"Indeed, this is my mistake, thanks","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6720b5fd04568f05fa5130ec7f815df1ae34b56a","unresolved":false,"context_lines":[{"line_number":649,"context_line":"                         {\"uuid\": guest.id, \"ex\": e})"},{"line_number":650,"context_line":"                continue"},{"line_number":651,"context_line":"            except Exception:"},{"line_number":652,"context_line":"                continue"},{"line_number":653,"context_line":"            sources \u003d doc.findall(\"./devices/disk[@type\u003d\u0027file\u0027]/source\")"},{"line_number":654,"context_line":"            for source in sources:"},{"line_number":655,"context_line":"                devices.append(source.get(\u0027file\u0027))"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_5b48f92d","line":652,"updated":"2016-05-27 16:25:41.000000000","message":"What is this catching? We should definitely be able to handle any of the errors that parsing our own XML throws.","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f4fd562a1d9cb2a2d900c3e5b5c893e9849f64a3","unresolved":false,"context_lines":[{"line_number":649,"context_line":"                         {\"uuid\": guest.id, \"ex\": e})"},{"line_number":650,"context_line":"                continue"},{"line_number":651,"context_line":"            except Exception:"},{"line_number":652,"context_line":"                continue"},{"line_number":653,"context_line":"            sources \u003d doc.findall(\"./devices/disk[@type\u003d\u0027file\u0027]/source\")"},{"line_number":654,"context_line":"            for source in sources:"},{"line_number":655,"context_line":"                devices.append(source.get(\u0027file\u0027))"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_c0df2738","line":652,"in_reply_to":"9abb7d3a_5b48f92d","updated":"2016-06-01 12:28:48.000000000","message":"I can\u0027t find what exception should be catch for fromstring() by google, I just refer like this code:\nhttps://github.com/openstack/nova/blob/master/nova/virt/libvirt/driver.py#L7224\nIf you know it, please tell me.","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":457,"context_line":"        return \u0027.\u0027.join([str(x) for x in version])"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"    def _get_all_file_devices(self):"},{"line_number":460,"context_line":"        \"\"\"Return all file devices in use on this node.\"\"\""},{"line_number":461,"context_line":"        devices \u003d []"},{"line_number":462,"context_line":"        for guest in self._host.list_guests():"},{"line_number":463,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_dbad40ea","line":460,"updated":"2016-07-21 13:56:48.000000000","message":"This is a horribly pretty misleading method name \u0026 doc. You\u0027re not returning devices  at all - you\u0027re returning file paths.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":461,"context_line":"        devices \u003d []"},{"line_number":462,"context_line":"        for guest in self._host.list_guests():"},{"line_number":463,"context_line":"            try:"},{"line_number":464,"context_line":"                doc \u003d etree.fromstring(guest.get_xml_desc())"},{"line_number":465,"context_line":"            except libvirt.libvirtError as e:"},{"line_number":466,"context_line":"                LOG.warn(_LW(\"couldn\u0027t obtain the XML from domain:\""},{"line_number":467,"context_line":"                             \" %(uuid)s, exception: %(ex)s\") %"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_9b70e8a5","line":464,"updated":"2016-07-21 13:56:48.000000000","message":"Please don\u0027t do invent more adhoc XML parsing. Use guest.get_all_disks() and access those objects.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":474,"context_line":"                devices.append(source.get(\u0027file\u0027))"},{"line_number":475,"context_line":"        return devices"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    def _init_mount_path_usage(self):"},{"line_number":478,"context_line":"        \"\"\"Initialize mount_path_usage with volumes already mounted\"\"\""},{"line_number":479,"context_line":"        devices \u003d self._get_all_file_devices()"},{"line_number":480,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_35320aa8","line":477,"updated":"2016-09-01 16:50:24.000000000","message":"This function is purely for updating module data in fs. It should be in fs, not driver. And as Dan B says, _get_all_file_devices shouldn\u0027t exist at all.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":479,"context_line":"        devices \u003d self._get_all_file_devices()"},{"line_number":480,"context_line":""},{"line_number":481,"context_line":"        for device in devices:"},{"line_number":482,"context_line":"            mount_path, vol_name \u003d device.rsplit(\u0027/\u0027, 1)"},{"line_number":483,"context_line":"            fs.mount_path_usage[mount_path].append(vol_name)"},{"line_number":484,"context_line":""},{"line_number":485,"context_line":"    def init_host(self, host):"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_7b3a549a","line":482,"updated":"2016-07-21 13:56:48.000000000","message":"This is assuming that the mount path matches the directory immediately holding the file. While this might be true today, I think its a pretty bad assumption to make.\n\nYou should get the actual list of mount paths on the host from /proc/mouts","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":557,"context_line":"                     \u0027qemu_ver\u0027: self._version_to_string("},{"line_number":558,"context_line":"                        MIN_QEMU_OTHER_ARCH.get(kvm_arch))})"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        self._init_mount_path_usage()"},{"line_number":561,"context_line":""},{"line_number":562,"context_line":"    def _check_required_migration_flags(self, migration_flags, config_name):"},{"line_number":563,"context_line":"        if CONF.libvirt.virt_type \u003d\u003d \u0027xen\u0027:"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_f51422ea","line":560,"updated":"2016-09-01 16:50:24.000000000","message":"This could be fs.init_mount_path() or whatever.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"bb5cc19ab1c6e8d754f6f526a67ebd7378aa28c4","unresolved":false,"context_lines":[{"line_number":467,"context_line":"            try:"},{"line_number":468,"context_line":"                doc \u003d etree.fromstring(guest.get_xml_desc())"},{"line_number":469,"context_line":"            except libvirt.libvirtError as e:"},{"line_number":470,"context_line":"                LOG.warn(_LW(\"couldn\u0027t obtain the XML from domain:\""},{"line_number":471,"context_line":"                             \" %(uuid)s, exception: %(ex)s\") %"},{"line_number":472,"context_line":"                         {\"uuid\": guest.id, \"ex\": e})"},{"line_number":473,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8ec9b2_7f7919fc","line":470,"updated":"2016-09-14 13:51:53.000000000","message":"LOG.warn is deprecated, please use LOG.warning","commit_id":"5888308e3e5d2dfda849e4f1bd81a25d462cf27c"},{"author":{"_account_id":6962,"name":"Kashyap Chamarthy","email":"kchamart@redhat.com","username":"kashyapc"},"change_message_id":"a620a4c29c807ca1328ef5105bead941b803e807","unresolved":false,"context_lines":[{"line_number":467,"context_line":"            try:"},{"line_number":468,"context_line":"                doc \u003d etree.fromstring(guest.get_xml_desc())"},{"line_number":469,"context_line":"            except libvirt.libvirtError as e:"},{"line_number":470,"context_line":"                LOG.warn(_LW(\"couldn\u0027t obtain the XML from domain:\""},{"line_number":471,"context_line":"                             \" %(uuid)s, exception: %(ex)s\") %"},{"line_number":472,"context_line":"                         {\"uuid\": guest.id, \"ex\": e})"},{"line_number":473,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a95cdbc_2e6053ce","line":470,"in_reply_to":"7a8ec9b2_7f7919fc","updated":"2016-10-05 07:57:57.000000000","message":"Yes, I already have this change done locally.  But still working out rest of the details.  I\u0027ve only began examining this change recently, as you could see.","commit_id":"5888308e3e5d2dfda849e4f1bd81a25d462cf27c"}],"nova/virt/libvirt/volume/fs.py":[{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"21a08add465670dccd8dfa25cab12dafb7c36659","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_ceffe1ff","line":98,"updated":"2016-03-16 16:01:21.000000000","message":"I like your idea with export_synchronized, maybe you should put it there either?\n\nwhat after ine 103 another thread will run , delete resource and entire list from export_usage dict. Then thread 1 will call remove to None.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"7eff53136eb0cef33563b4f2d4790f4450fdbb89","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_f4019eb0","line":98,"in_reply_to":"1af94dfe_4add620d","updated":"2016-03-17 12:32:06.000000000","message":"Yeah, think this is safe. However, it could do with a comment to say that this function should only be called when holding the export lock.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"876c673a1a8559cd7f60e9c9529cf7e493e65500","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_c0749c69","line":98,"in_reply_to":"1af94dfe_4add620d","updated":"2016-03-17 13:24:46.000000000","message":"You may be right, but where do you acquire lock named \"export\"?","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f8581948aa8897c8a5ab1953f85617d430a1726c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_6cb91e15","line":98,"in_reply_to":"1af94dfe_c0749c69","updated":"2016-03-18 06:22:50.000000000","message":"like this:\n    @utils.export_synchronized\n    def disconnect_volume(self, connection_info, disk_dev):\n\nwhen come into disconnect_volume(), the lock will be acquired.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"6b5435a636e281626d39c9e62303e09e32388f98","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_4add620d","line":98,"in_reply_to":"1af94dfe_ceffe1ff","updated":"2016-03-17 02:15:44.000000000","message":"I don\u0027t think so, any operation on \"export\" must acquire the lock named of \"export\" firstly, which defined in export_synchronized(), so if one thread into update_export_usage(), then another one can\u0027t into it,thanks.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f8581948aa8897c8a5ab1953f85617d430a1726c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\""},{"line_number":96,"context_line":"        mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":97,"context_line":"        return os.path.join(mount_path, connection_info[\u0027data\u0027][\u0027name\u0027])"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def update_export_usage(self, export, resource, connected\u003dTrue):"},{"line_number":100,"context_line":"        if connected:"},{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_8c53cae1","line":98,"in_reply_to":"1af94dfe_f4019eb0","updated":"2016-03-18 06:22:50.000000000","message":"Done","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"7eff53136eb0cef33563b4f2d4790f4450fdbb89","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"},{"line_number":102,"context_line":"        else:"},{"line_number":103,"context_line":"            if resource in self.export_usage[export]:"},{"line_number":104,"context_line":"                self.export_usage[export].remove(resource)"},{"line_number":105,"context_line":"            if not self.export_usage[export]:"},{"line_number":106,"context_line":"                del self.export_usage[export]"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_86e8f9b5","line":104,"updated":"2016-03-17 12:32:06.000000000","message":"A warning if it\u0027s not there would be a good way to catch a potential usage bug.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"e0ade070cb446950763f6e89c24665c5b075a445","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"},{"line_number":102,"context_line":"        else:"},{"line_number":103,"context_line":"            if resource in self.export_usage[export]:"},{"line_number":104,"context_line":"                self.export_usage[export].remove(resource)"},{"line_number":105,"context_line":"            if not self.export_usage[export]:"},{"line_number":106,"context_line":"                del self.export_usage[export]"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_2071bb0f","line":104,"in_reply_to":"1af94dfe_27129157","updated":"2016-03-18 15:20:40.000000000","message":"It would indicate an accounting bug that needs to be fixed.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f8581948aa8897c8a5ab1953f85617d430a1726c","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            self.export_usage[export].append(resource)"},{"line_number":102,"context_line":"        else:"},{"line_number":103,"context_line":"            if resource in self.export_usage[export]:"},{"line_number":104,"context_line":"                self.export_usage[export].remove(resource)"},{"line_number":105,"context_line":"            if not self.export_usage[export]:"},{"line_number":106,"context_line":"                del self.export_usage[export]"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_27129157","line":104,"in_reply_to":"1af94dfe_86e8f9b5","updated":"2016-03-18 06:22:50.000000000","message":"why need add warning message here? if self.export_usage[export] is None, it illustrates the share file named \u0027export\u0027 was umounted， then self.export_usage[export] should be deleted.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        mount_path lock."},{"line_number":118,"context_line":"        \"\"\""},{"line_number":119,"context_line":"        if connected:"},{"line_number":120,"context_line":"            mount_path_usage[mount_path].append(vol_name)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            if vol_name in mount_path_usage[mount_path]:"},{"line_number":123,"context_line":"                mount_path_usage[mount_path].remove(vol_name)"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_521697f1","line":120,"updated":"2016-05-20 12:10:46.000000000","message":"minor: we can return here","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"2ccbe3ed0921aaad9ad9b3e5de71e49d735e8147","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        mount_path lock."},{"line_number":118,"context_line":"        \"\"\""},{"line_number":119,"context_line":"        if connected:"},{"line_number":120,"context_line":"            mount_path_usage[mount_path].append(vol_name)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            if vol_name in mount_path_usage[mount_path]:"},{"line_number":123,"context_line":"                mount_path_usage[mount_path].remove(vol_name)"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_291170b0","line":120,"in_reply_to":"bab6814e_521697f1","updated":"2016-05-24 08:46:46.000000000","message":"what\u0027s mean?  like this?\n if connected:\n     return mount_path_usage[mount_path].append(vol_name)","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6720b5fd04568f05fa5130ec7f815df1ae34b56a","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"mount_path_usage \u003d collections.defaultdict(list)"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"def mount_path_synchronized(f):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_7b7cdd20","line":28,"updated":"2016-05-27 16:25:41.000000000","message":"I would much prefer that we store this data in the libvirt driver object instead as a global in this module. It\u0027s a little more complicated but I think I would have refactored the interface to provide a callback or something to the methods we\u0027re calling in the storage drivers.\n\nAlso, I\u0027m worried that we might let this get stale and never unmount some things as a result. I wonder if it wouldn\u0027t be better to never unmount synchronously and poll for usage of each mount periodically and lazy-unmount things in a place where we can synchronize on a lock in the libvirt driver itself?","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f4fd562a1d9cb2a2d900c3e5b5c893e9849f64a3","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"mount_path_usage \u003d collections.defaultdict(list)"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"def mount_path_synchronized(f):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9abb7d3a_34175149","line":28,"in_reply_to":"9abb7d3a_7b7cdd20","updated":"2016-06-01 12:28:48.000000000","message":"@Dan, thanks for you advice, storing mount data in libvirt driver object is ok too, just need modify _get_mount_path() to get_mount_path(), then add mount_path_synchronized() to _connect_volume and _disconnect_volume and judge the volume driver is nfs/sambfs/glusterfs, right?\n\nI wonder why we get stale mount data, unmount synchronizing isn\u0027t enough?\nthanks again.","commit_id":"1f2be22868d163af67f97efecdf166345e5ec4a7"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            mount_path_usage[mount_path].append(vol_name)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            if vol_name in mount_path_usage[mount_path]:"},{"line_number":123,"context_line":"                mount_path_usage[mount_path].remove(vol_name)"},{"line_number":124,"context_line":"            else:"},{"line_number":125,"context_line":"                LOG.warn(_LW(\u0027Volume name %(vol_name)s not found in \u0027"},{"line_number":126,"context_line":"                             \u0027mount_path_usage: %(mnt_path_usage)s\u0027),"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_9bb2a8e3","line":123,"updated":"2016-07-21 13:56:48.000000000","message":"This looks fragile if we have a sitation where 2 instances on a host connect to the same volume. IMHO it\u0027d be better to maintain a list of attachments per volume, rather than merely rely on existence of the volume. ie have a dict of dicts instead of just a dict of lists","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            mount_path_usage[mount_path].append(vol_name)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            if vol_name in mount_path_usage[mount_path]:"},{"line_number":123,"context_line":"                mount_path_usage[mount_path].remove(vol_name)"},{"line_number":124,"context_line":"            else:"},{"line_number":125,"context_line":"                LOG.warn(_LW(\u0027Volume name %(vol_name)s not found in \u0027"},{"line_number":126,"context_line":"                             \u0027mount_path_usage: %(mnt_path_usage)s\u0027),"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_f54342ad","line":123,"in_reply_to":"dada55a8_9bb2a8e3","updated":"2016-09-01 16:50:24.000000000","message":"Actually I think this is ok, because list.remove() only removes the first matching entry from the list. This is also a simpler data structure, so without a user for anything more comprehensive I\u0027d be inclined to KISS.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                              \u0027mnt_path_usage\u0027: mount_path_usage})"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"            if not mount_path_usage[mount_path]:"},{"line_number":131,"context_line":"                del mount_path_usage[mount_path]"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def is_mount_path_in_use(self, mount_path):"},{"line_number":134,"context_line":"        return mount_path in mount_path_usage"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_5b8e702e","line":131,"updated":"2016-07-21 13:56:48.000000000","message":"Overloading 2 method to have 2 distinct actions is not very nice, as it obscures what is going on from the caller.\n\nWe should have separate methods with clear names like  \u0027add_volume_usage()\u0027 and \u0027remove_volume_usage()\u0027","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":128,"context_line":"                              \u0027mnt_path_usage\u0027: mount_path_usage})"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"            if not mount_path_usage[mount_path]:"},{"line_number":131,"context_line":"                del mount_path_usage[mount_path]"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def is_mount_path_in_use(self, mount_path):"},{"line_number":134,"context_line":"        return mount_path in mount_path_usage"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_35c20aea","line":131,"in_reply_to":"dada55a8_5b8e702e","updated":"2016-09-01 16:50:24.000000000","message":"+1","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"bb5cc19ab1c6e8d754f6f526a67ebd7378aa28c4","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            if vol_name in mount_path_usage[mount_path]:"},{"line_number":123,"context_line":"                mount_path_usage[mount_path].remove(vol_name)"},{"line_number":124,"context_line":"            else:"},{"line_number":125,"context_line":"                LOG.warn(_LW(\u0027Volume name %(vol_name)s not found in \u0027"},{"line_number":126,"context_line":"                             \u0027mount_path_usage: %(mnt_path_usage)s\u0027),"},{"line_number":127,"context_line":"                             {\u0027vol_name\u0027: vol_name,"},{"line_number":128,"context_line":"                              \u0027mnt_path_usage\u0027: mount_path_usage})"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a8ec9b2_df886dea","line":125,"updated":"2016-09-14 13:51:53.000000000","message":"LOG.warn is deprecated, please use LOG.warning","commit_id":"5888308e3e5d2dfda849e4f1bd81a25d462cf27c"}],"nova/virt/libvirt/volume/glusterfs.py":[{"author":{"_account_id":15524,"name":"dane-fichter","email":"dane.fichter@jhuapl.edu","username":"dane-fichter"},"change_message_id":"30da1ec19cfc64040d4ccb677c1341e24c2a344c","unresolved":false,"context_lines":[{"line_number":103,"context_line":"                utils.execute(\u0027umount\u0027, mount_path, run_as_root\u003dTrue)"},{"line_number":104,"context_line":"            except processutils.ProcessExecutionError:"},{"line_number":105,"context_line":"                LOG.exception(_LE(\"Couldn\u0027t unmount the\""},{"line_number":106,"context_line":"                                  \"GlusterFS share %s\"), export)"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    def _ensure_mounted(self, glusterfs_export, mount_path, options):"},{"line_number":109,"context_line":"        if not libvirt_utils.is_mounted(mount_path, glusterfs_export):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a122d0e_87a52da3","line":106,"updated":"2016-04-29 13:22:10.000000000","message":"You lost a space in this error string while wrapping the line.","commit_id":"dbb5ddc2b295b0576715108192f4351ac769dd58"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        return conf"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @fs.mount_path_synchronized"},{"line_number":60,"context_line":"    def connect_volume(self, connection_info, mount_device):"},{"line_number":61,"context_line":"        if \u0027gluster\u0027 not in CONF.libvirt.qemu_allowed_storage_drivers:"},{"line_number":62,"context_line":"            vol_name \u003d connection_info[\u0027data\u0027][\u0027name\u0027]"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_5832655f","line":59,"updated":"2016-09-01 16:50:24.000000000","message":"As below, we don\u0027t need to synchronize this whole function, and it\u0027s not desirable.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"            self.update_mount_path_usage(mount_path, vol_name)"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            self._ensure_mounted(export, mount_path, options)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"            connection_info[\u0027data\u0027][\u0027device_path\u0027] \u003d \\"},{"line_number":72,"context_line":"                self._get_device_path(connection_info)"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_fb05a445","line":69,"updated":"2016-07-21 13:56:48.000000000","message":"IMHO, it\u0027d be nicer to have _ensure_mounted be responsible for updating the usage cache, as that ensures it can\u0027t be forgotten.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            connection_info[\u0027data\u0027][\u0027device_path\u0027] \u003d \\"},{"line_number":72,"context_line":"                self._get_device_path(connection_info)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    @fs.mount_path_synchronized"},{"line_number":75,"context_line":"    def disconnect_volume(self, connection_info, disk_dev):"},{"line_number":76,"context_line":"        \"\"\"Disconnect the volume.\"\"\""},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_58e425df","line":74,"updated":"2016-09-01 16:50:24.000000000","message":"This isn\u0027t necessary or desirable. We\u0027re basically synchronizing all volume attach/detach calls with this. The only thing that needs to be synchronized is update_mount_path_usage, so this decorator could just live there.\n\nIf you split that function in 2, as suggested, the remove function could return something indicating whether this was the last user, and therefore whether we should unmount.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"794cb8dc853d82398f678410eabe824e661d57d7","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                utils.execute(\u0027umount\u0027, mount_path, run_as_root\u003dTrue)"},{"line_number":91,"context_line":"            except processutils.ProcessExecutionError:"},{"line_number":92,"context_line":"                LOG.exception(_LE(\"Couldn\u0027t unmount the \""},{"line_number":93,"context_line":"                                  \"GlusterFS share %s\"), export)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def _ensure_mounted(self, glusterfs_export, mount_path, options):"},{"line_number":96,"context_line":"        if not libvirt_utils.is_mounted(mount_path, glusterfs_export):"}],"source_content_type":"text/x-python","patch_set":12,"id":"dada55a8_9bb8e876","line":93,"updated":"2016-07-21 13:56:48.000000000","message":"IMHO, we should have a \u0027_maybe_unmount\u0027 method int he parent class which deal with updating the mount usage cache, and calling umount in one operation.\n\nIn fact I think it be would nice to completely separate mount handling from the volume calsses.\n\nHave a nova/virt/libvirt/mount.py file which defines a \"MountManager\" class. There\u0027d a single instance of this associated with the libvirt driver, and it can be passed into the volume class constructor. This MountManager class would have mount + unmount methods, and internally maintain the cache/record of everything which is mounted.\n\nThese volume classes would simply invoke the mount/unmount methods on that class and not have to worry about anything else.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"3e6a5d17503ec15911b99c0384e2b257a94d2c44","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                utils.execute(\u0027umount\u0027, mount_path, run_as_root\u003dTrue)"},{"line_number":91,"context_line":"            except processutils.ProcessExecutionError:"},{"line_number":92,"context_line":"                LOG.exception(_LE(\"Couldn\u0027t unmount the \""},{"line_number":93,"context_line":"                                  \"GlusterFS share %s\"), export)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def _ensure_mounted(self, glusterfs_export, mount_path, options):"},{"line_number":96,"context_line":"        if not libvirt_utils.is_mounted(mount_path, glusterfs_export):"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_d852f5dd","line":93,"in_reply_to":"dada55a8_9bb8e876","updated":"2016-09-01 16:50:24.000000000","message":"+1\n\nI\u0027d personally take that as follow-on, though, unless we have somebody prepared to do the work now. I don\u0027t think this patch is adding technical debt, maybe just not reducing it as much as it might.","commit_id":"c3ed0b87521b168967d2bf53b244e767c5787602"}],"nova/virt/libvirt/volume/nfs.py":[{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"3e19bc6e9d1e9ec72584cec14bf0ab970a99e17e","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        export \u003d connection_info[\u0027data\u0027][\u0027export\u0027]"},{"line_number":73,"context_line":"        self.update_export_usage(export, vol_name, connected\u003dFalse)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        if not self.is_export_in_use(export):"},{"line_number":76,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5aef4532_a6f12798","line":75,"updated":"2016-03-11 09:43:40.000000000","message":"But, what if another thread will interrupt current thread here and call self.update_export_usage(export, vol_name) ?\nMaybe double checking should be done here and entire disconnect section should be synchronized? The same for another fs providers.","commit_id":"d2c8dbec3db6ca1f4ef00a48e81a84e52cd3b404"},{"author":{"_account_id":12712,"name":"Gleb Stepanov","email":"gstepanov@mirantis.com","username":"stgleb"},"change_message_id":"ef6ee06c0c553b017771dc155cc1213ae94540e8","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        export \u003d connection_info[\u0027data\u0027][\u0027export\u0027]"},{"line_number":73,"context_line":"        self.update_export_usage(export, vol_name, connected\u003dFalse)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        if not self.is_export_in_use(export):"},{"line_number":76,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1af94dfe_534a71c6","line":75,"in_reply_to":"1af94dfe_10c57f8d","updated":"2016-03-16 09:54:18.000000000","message":"I think it will be ok if you\u0027ve made disconnect_volume synchronized at all. I guess it is enough.","commit_id":"d2c8dbec3db6ca1f4ef00a48e81a84e52cd3b404"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"7255eb9b872a8d4dc9509b4ffce5f58b55c1a735","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        export \u003d connection_info[\u0027data\u0027][\u0027export\u0027]"},{"line_number":73,"context_line":"        self.update_export_usage(export, vol_name, connected\u003dFalse)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        if not self.is_export_in_use(export):"},{"line_number":76,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1af94dfe_10c57f8d","line":75,"in_reply_to":"5aef4532_a6f12798","updated":"2016-03-16 09:27:40.000000000","message":"Hi gleb, thank you for your review, but I wonder how to double checking here?   Yes, disconnect section should be synchronized,","commit_id":"d2c8dbec3db6ca1f4ef00a48e81a84e52cd3b404"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"7eff53136eb0cef33563b4f2d4790f4450fdbb89","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\"Disconnect the volume.\"\"\""},{"line_number":73,"context_line":"        vol_name \u003d connection_info[\u0027data\u0027][\u0027name\u0027]"},{"line_number":74,"context_line":"        export \u003d connection_info[\u0027data\u0027][\u0027export\u0027]"},{"line_number":75,"context_line":"        self.update_export_usage(export, vol_name, connected\u003dFalse)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        if not self.is_export_in_use(export):"},{"line_number":78,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_94d01af8","line":75,"updated":"2016-03-17 12:32:06.000000000","message":"umount below could fail. If that happens, your export usage is out of sync with reality. You need to handle that somehow. This applies to all 3 backends you\u0027ve touched.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"f8581948aa8897c8a5ab1953f85617d430a1726c","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\"Disconnect the volume.\"\"\""},{"line_number":73,"context_line":"        vol_name \u003d connection_info[\u0027data\u0027][\u0027name\u0027]"},{"line_number":74,"context_line":"        export \u003d connection_info[\u0027data\u0027][\u0027export\u0027]"},{"line_number":75,"context_line":"        self.update_export_usage(export, vol_name, connected\u003dFalse)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        if not self.is_export_in_use(export):"},{"line_number":78,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1af94dfe_c7612d3b","line":75,"in_reply_to":"1af94dfe_94d01af8","updated":"2016-03-18 06:22:50.000000000","message":"even though umount fail here, but detach_volume is success, export_usage just records running volumes, so I don\u0027t think we need think about this problem, thanks.","commit_id":"4b0c4d66f0e7e626297f707cc468fece4c6afbde"}],"nova/virt/libvirt/volume/smbfs.py":[{"author":{"_account_id":1865,"name":"Andrea Rosa","email":"andrea.rosa@gmail.com","username":"andrea-rosa-m"},"change_message_id":"bfca416fca3988c321f2f4c1923c6f705c382bda","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                                     connected\u003dFalse)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        if not self.is_mount_path_in_use(mount_path):"},{"line_number":86,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":87,"context_line":"            remotefs.unmount_share(mount_path, smbfs_share)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def _parse_mount_options(self, connection_info):"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_0dceb481","line":86,"range":{"start_line":86,"start_character":12,"end_line":86,"end_character":62},"updated":"2016-05-20 12:10:46.000000000","message":"we already have the mount_path, why do we need to get it again?","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"},{"author":{"_account_id":7653,"name":"Zhengguang Ou","email":"zhengguangou@gmail.com","username":"Zhengguang"},"change_message_id":"2ccbe3ed0921aaad9ad9b3e5de71e49d735e8147","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                                     connected\u003dFalse)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        if not self.is_mount_path_in_use(mount_path):"},{"line_number":86,"context_line":"            mount_path \u003d self._get_mount_path(connection_info)"},{"line_number":87,"context_line":"            remotefs.unmount_share(mount_path, smbfs_share)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def _parse_mount_options(self, connection_info):"}],"source_content_type":"text/x-python","patch_set":7,"id":"bab6814e_c9d704ec","line":86,"range":{"start_line":86,"start_character":12,"end_line":86,"end_character":62},"in_reply_to":"bab6814e_0dceb481","updated":"2016-05-24 08:46:46.000000000","message":"indeed, thanks.","commit_id":"9a86e5ac5eea133d0548a7e22c598ffdd056cf85"}]}
