Clean up iSCSI multipath devices in Post Live Migration

When a volume is attached to a VM in the source compute node through
multipath, the related files in /dev/disk/by-path/ are like this

stack@ubuntu-server12:~/devstack$ ls /dev/disk/by-path/*24
/dev/disk/by-path/ip-192.168.3.50:3260-iscsi-iqn.1992-04.com.emc:cx.
fnm00124500890.a5-lun-24
/dev/disk/by-path/ip-192.168.4.51:3260-iscsi-iqn.1992-04.com.emc:cx.
fnm00124500890.b4-lun-24

The information on its corresponding multipath device is like this
stack@ubuntu-server12:~/devstack$ sudo multipath -l 3600601602ba034
00921130967724e411
3600601602ba03400921130967724e411 dm-3 DGC,VRAID
size=1.0G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
|-+- policy='round-robin 0' prio=-1 status=active
| `- 19:0:0:24 sdl 8:176 active undef running
`-+- policy='round-robin 0' prio=-1 status=enabled
  `- 18:0:0:24 sdj 8:144 active undef running

But when the VM is migrated to the destination, the related information is
like the following example since we CANNOT guarantee that all nodes are able
to access the same iSCSI portals and the same target LUN number. And the
information is used to overwrite connection_info in the DB before the post
live migration logic is executed.

stack@ubuntu-server13:~/devstack$ ls /dev/disk/by-path/*24
/dev/disk/by-path/ip-192.168.3.51:3260-iscsi-iqn.1992-04.com.emc:cx.
fnm00124500890.b5-lun-100
/dev/disk/by-path/ip-192.168.4.51:3260-iscsi-iqn.1992-04.com.emc:cx.
fnm00124500890.b4-lun-100

stack@ubuntu-server13:~/devstack$ sudo multipath -l 3600601602ba034
00921130967724e411
3600601602ba03400921130967724e411 dm-3 DGC,VRAID
size=1.0G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
|-+- policy='round-robin 0' prio=-1 status=active
| `- 19:0:0:100 sdf 8:176 active undef running
`-+- policy='round-robin 0' prio=-1 status=enabled
  `- 18:0:0:100 sdg 8:144 active undef running

As a result, if post live migration in source side uses <IP>, <IQN> and
<TARGET LUN Number> to find the devices to clean up, it may use 192.168.3.51,
iqn.1992-04.com.emc:cx.fnm00124500890.a5 and 100.
However, the correct one should be 192.168.3.50, iqn.1992-04.com.emc:cx.
fnm00124500890.a5 and 24.

Similar philosophy in (https://bugs.launchpad.net/nova/+bug/1327497) can be
used to fix it: Leverage the unchanged multipath_id to find correct devices
to delete.

Change-Id: I875293c3ade9423caa2b8afe9eca25a74606d262
Closes-Bug: #1357368
(cherry picked from commit aa9104cced)
This commit is contained in:
Jeegn Chen 2014-08-15 21:40:14 +08:00 committed by Xing Yang
parent b86bcb9358
commit 9c3ec16576
2 changed files with 37 additions and 1 deletions

View File

@ -393,6 +393,36 @@ Setting up iSCSI targets: unused
self.assertEqual('block', tree.get('type'))
self.assertEqual(dev_path, tree.find('./source').get('dev'))
def test_libvirt_iscsi_driver_multipath_id(self):
libvirt_driver = volume.LibvirtISCSIVolumeDriver(self.fake_conn)
libvirt_driver.use_multipath = True
self.stubs.Set(libvirt_driver, '_run_iscsiadm_bare',
lambda x, check_exit_code: ('',))
self.stubs.Set(libvirt_driver, '_rescan_iscsi', lambda: None)
self.stubs.Set(libvirt_driver, '_get_host_device', lambda x: None)
self.stubs.Set(libvirt_driver, '_rescan_multipath', lambda: None)
fake_multipath_id = 'fake_multipath_id'
fake_multipath_device = '/dev/mapper/%s' % fake_multipath_id
self.stubs.Set(libvirt_driver, '_get_multipath_device_name',
lambda x: fake_multipath_device)
def fake_disconnect_volume_multipath_iscsi(iscsi_properties,
multipath_device):
if fake_multipath_device != multipath_device:
raise Exception('Invalid multipath_device.')
self.stubs.Set(libvirt_driver, '_disconnect_volume_multipath_iscsi',
fake_disconnect_volume_multipath_iscsi)
with mock.patch.object(os.path, 'exists', return_value=True):
vol = {'id': 1, 'name': self.name}
connection_info = self.iscsi_connection(vol, self.location,
self.iqn)
libvirt_driver.connect_volume(connection_info,
self.disk_info)
self.assertEqual(fake_multipath_id,
connection_info['data']['multipath_id'])
libvirt_driver.disconnect_volume(connection_info, "fake")
def test_sanitize_log_run_iscsiadm(self):
# Tests that the parameters to the _run_iscsiadm function are sanitized
# for passwords when logged.

View File

@ -334,6 +334,8 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
if multipath_device is not None:
host_device = multipath_device
connection_info['data']['multipath_id'] = \
multipath_device.split('/')[-1]
connection_info['data']['host_device'] = host_device
return self.get_config(connection_info, disk_info)
@ -345,7 +347,11 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver):
host_device = self._get_host_device(iscsi_properties)
multipath_device = None
if self.use_multipath:
multipath_device = self._get_multipath_device_name(host_device)
if 'multipath_id' in iscsi_properties:
multipath_device = ('/dev/mapper/%s' %
iscsi_properties['multipath_id'])
else:
multipath_device = self._get_multipath_device_name(host_device)
super(LibvirtISCSIVolumeDriver,
self).disconnect_volume(connection_info, disk_dev)