iSCSI detect multipath DM with no WWN

If udev rules are slow (or don't happen) and they don't generate the
symlinks we use to detect the WWN, or if we just fail to find the WWN we
end up not detecting the iSCSI multipath even if it is present in the
system.

With this patch we no longer wait to find the WWN before trying to
locate the multipath device.

This means that as long as the multipath daemon is able to generate the
multipath we will be able to return a multipath device path to the
caller.

This backport has been tuned to properly work with Python 2 too, where
the number of calls to get_wwn_mock may be higher than 2
because the thread may not start immediately as it happens on Python 3.x.

Closes-Bug: 1881619
Change-Id: Ic48bd9ac408c56073e58168df7e74e4b949ac2f2
(cherry picked from commit 63f52be546)
(cherry picked from commit a04e553add)
This commit is contained in:
Gorka Eguileor 2020-06-01 18:38:45 +02:00 committed by Luigi Toscano
parent 7eec31b6c4
commit 57ac89910e
3 changed files with 45 additions and 3 deletions

View File

@ -738,10 +738,10 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
# We have devices but we don't know the wwn yet
if not wwn and found:
wwn = self._linuxscsi.get_sysfs_wwn(found)
# We have the wwn but not a multipath
if wwn and not mpath:
if not mpath and found:
mpath = self._linuxscsi.find_sysfs_multipath_dm(found)
if not (mpath or wwn_added):
# We have the wwn but not a multipath
if wwn and not(mpath or wwn_added):
# Tell multipathd that this wwn is a multipath and hint
# multipathd to recheck all the devices we have just
# connected. We only do this once, since for any new

View File

@ -1211,6 +1211,42 @@ Setting up iSCSI targets: unused
self.assertGreaterEqual(find_dm_mock.call_count, 2)
self.assertEqual(4, connect_mock.call_count)
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_sysfs_multipath_dm',
side_effect=[None, 'dm-0'])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwn', return_value='')
@mock.patch.object(linuxscsi.LinuxSCSI, 'multipath_add_path')
@mock.patch.object(linuxscsi.LinuxSCSI, 'multipath_add_wwid')
@mock.patch.object(iscsi.ISCSIConnector, '_connect_vol')
@mock.patch('time.sleep')
def test_connect_multipath_volume_no_wwid(self, sleep_mock, connect_mock,
add_wwid_mock, add_path_mock,
get_wwn_mock, find_dm_mock):
# Even if we don't have the wwn we'll be able to find the multipath
def my_connect(rescans, props, data):
devs = {'tgt1': 'sda', 'tgt2': 'sdb', 'tgt3': 'sdc', 'tgt4': 'sdd'}
data['stopped_threads'] += 1
data['num_logins'] += 1
dev = devs[props['target_iqn']]
data['found_devices'].append(dev)
data['just_added_devices'].append(dev)
connect_mock.side_effect = my_connect
res = self.connector._connect_multipath_volume(self.CON_PROPS)
expected = {'type': 'block', 'scsi_wwn': '', 'multipath_id': '',
'path': '/dev/dm-0'}
self.assertEqual(expected, res)
self.assertGreaterEqual(get_wwn_mock.call_count, 2)
result = list(get_wwn_mock.call_args[0][0])
result.sort()
self.assertEqual(['sda', 'sdb', 'sdc', 'sdd'], result)
add_wwid_mock.assert_not_called()
add_path_mock.assert_not_called()
self.assertGreaterEqual(find_dm_mock.call_count, 2)
self.assertEqual(4, connect_mock.call_count)
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_sysfs_multipath_dm',
side_effect=[None, 'dm-0'])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwn',

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Improve iSCSI multipath detection to work even if we cannot find the
volume's WWN in sysfs.
(bug 1881619).