diff options
author | Jenkins <jenkins@review.openstack.org> | 2013-05-16 13:13:04 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2013-05-16 13:13:04 +0000 |
commit | 5b51f6157941bc4fcd819b4b49b56ac837ea8b77 (patch) | |
tree | 4ff8089eac9ecd56cbcae793fda167b347b37f5e | |
parent | 56f5172f33bbd1da1b8749b7754805de44c3ab9c (diff) | |
parent | fc786dd469a15bda1b9d3c7bacf9f1771b9b9956 (diff) | |
download | nova-5b51f6157941bc4fcd819b4b49b56ac837ea8b77.tar.gz nova-5b51f6157941bc4fcd819b4b49b56ac837ea8b77.tar.xz nova-5b51f6157941bc4fcd819b4b49b56ac837ea8b77.zip |
Merge "Detach volume fails when using multipath iscsi"
-rw-r--r-- | nova/tests/test_libvirt_volume.py | 30 | ||||
-rw-r--r-- | nova/virt/libvirt/volume.py | 64 |
2 files changed, 71 insertions, 23 deletions
diff --git a/nova/tests/test_libvirt_volume.py b/nova/tests/test_libvirt_volume.py index 1186ed268..6d2dc9dce 100644 --- a/nova/tests/test_libvirt_volume.py +++ b/nova/tests/test_libvirt_volume.py @@ -389,6 +389,36 @@ class LibvirtVolumeTestCase(test.TestCase): self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) libvirt_driver.disconnect_volume(connection_info, 'vde') + def test_libvirt_kvm_volume_with_multipath_getmpdev(self): + self.flags(libvirt_iscsi_use_multipath=True) + self.stubs.Set(os.path, 'exists', lambda x: True) + libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn) + name0 = 'volume-00000000' + location0 = '10.0.2.15:3260' + iqn0 = 'iqn.2010-10.org.openstack:%s' % name0 + vol0 = {'id': 0, 'name': name0} + dev0 = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' % (location0, iqn0) + name = 'volume-00000001' + location = '10.0.2.15:3260' + iqn = 'iqn.2010-10.org.openstack:%s' % name + vol = {'id': 1, 'name': name} + dev = '/dev/disk/by-path/ip-%s-iscsi-%s-lun-1' % (location, iqn) + devs = [dev0, dev] + self.stubs.Set(self.fake_conn, 'get_all_block_devices', lambda: devs) + connection_info = self.iscsi_connection(vol, location, iqn) + mpdev_filepath = '/dev/mapper/foo' + disk_info = { + "bus": "virtio", + "dev": "vde", + "type": "disk", + } + target_portals = ['fake_portal1', 'fake_portal2'] + libvirt_driver._get_multipath_device_name = lambda x: mpdev_filepath + conf = libvirt_driver.connect_volume(connection_info, disk_info) + tree = conf.format_dom() + self.assertEqual(tree.find('./source').get('dev'), mpdev_filepath) + libvirt_driver.disconnect_volume(connection_info, 'vde') + def test_libvirt_nfs_driver(self): # NOTE(vish) exists is to make driver assume connecting worked mnt_base = '/mnt' diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py index eee25a52b..ef8818743 100644 --- a/nova/virt/libvirt/volume.py +++ b/nova/virt/libvirt/volume.py @@ -268,32 +268,20 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): @utils.synchronized('connect_volume') def disconnect_volume(self, connection_info, disk_dev): """Detach the volume from instance_name.""" + iscsi_properties = connection_info['data'] + multipath_device = None + if CONF.libvirt_iscsi_use_multipath: + host_device = ("/dev/disk/by-path/ip-%s-iscsi-%s-lun-%s" % + (iscsi_properties['target_portal'], + iscsi_properties['target_iqn'], + iscsi_properties.get('target_lun', 0))) + multipath_device = self._get_multipath_device_name(host_device) + super(LibvirtISCSIVolumeDriver, self).disconnect_volume(connection_info, disk_dev) - iscsi_properties = connection_info['data'] - if CONF.libvirt_iscsi_use_multipath and \ - "mapper" in connection_info['data']['device_path']: - self._rescan_iscsi() - self._rescan_multipath() - devices = [dev for dev in self.connection.get_all_block_devices() - if "/mapper/" in dev] - if not devices: - #disconnect if no other multipath devices - self._disconnect_mpath(iscsi_properties) - return - - other_iqns = [self._get_multipath_iqn(device) - for device in devices] - - if iscsi_properties['target_iqn'] not in other_iqns: - #disconnect if no other multipath devices with same iqn - self._disconnect_mpath(iscsi_properties) - return - - #else do not disconnect iscsi portals, - #as they are used for other luns - return + if CONF.libvirt_iscsi_use_multipath and multipath_device: + return self._disconnect_volume_multipath_iscsi(iscsi_properties) # NOTE(vish): Only disconnect from the target if no luns from the # target are in use. @@ -305,6 +293,36 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): if not devices: self._disconnect_from_iscsi_portal(iscsi_properties) + def _disconnect_volume_multipath_iscsi(self, iscsi_properties): + self._rescan_iscsi() + self._rescan_multipath() + block_devices = self.connection.get_all_block_devices() + devices = [] + for dev in block_devices: + if "/mapper/" in dev: + devices.append(dev) + else: + mpdev = self._get_multipath_device_name(dev) + if mpdev: + devices.append(mpdev) + + if not devices: + # disconnect if no other multipath devices + self._disconnect_mpath(iscsi_properties) + return + + other_iqns = [self._get_multipath_iqn(device) + for device in devices] + + if iscsi_properties['target_iqn'] not in other_iqns: + # disconnect if no other multipath devices with same iqn + self._disconnect_mpath(iscsi_properties) + return + + # else do not disconnect iscsi portals, + # as they are used for other luns + return + def _connect_to_iscsi_portal(self, iscsi_properties): # NOTE(vish): If we are on the same host as nova volume, the # discovery makes the target so we don't need to |