Merge "Leverage the iSCSI mpath to get the WWN"

This commit is contained in:
Zuul 2020-08-17 16:45:57 +00:00 committed by Gerrit Code Review
commit d792537776
4 changed files with 46 additions and 3 deletions

View File

@ -737,7 +737,7 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
data['failed_logins'])):
# We have devices but we don't know the wwn yet
if not wwn and found:
wwn = self._linuxscsi.get_sysfs_wwn(found)
wwn = self._linuxscsi.get_sysfs_wwn(found, mpath)
if not mpath and found:
mpath = self._linuxscsi.find_sysfs_multipath_dm(found)
# We have the wwn but not a multipath
@ -778,6 +778,8 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
if not mpath:
LOG.warning('No dm was created, connection to volume is probably '
'bad and will perform poorly.')
elif not wwn:
wwn = self._linuxscsi.get_sysfs_wwn(found, mpath)
return self._get_connect_result(connection_properties, wwn, found,
mpath)

View File

@ -127,8 +127,20 @@ class LinuxSCSI(executor.Executor):
LOG.debug('dev_info=%s', str(dev_info))
return dev_info
def get_sysfs_wwn(self, device_names):
def get_sysfs_wwn(self, device_names, mpath=None):
"""Return the wwid from sysfs in any of devices in udev format."""
# If we have a multipath DM we know that it has found the WWN
if mpath:
# We have the WWN in /uuid even with friendly names, unline /name
try:
with open('/sys/block/%s/dm/uuid' % mpath) as f:
# Contents are matph-WWN, so get the part we want
wwid = f.read().strip()[6:]
if wwid: # Check should not be needed, but just in case
return wwid
except Exception as exc:
LOG.warning('Failed to read the DM uuid: %s', exc)
wwid = self.get_sysfs_wwid(device_names)
glob_str = '/dev/disk/by-id/scsi-'
wwn_paths = glob.glob(glob_str + '*')

View File

@ -1206,6 +1206,8 @@ Setting up iSCSI targets: unused
result = list(get_wwn_mock.call_args[0][0])
result.sort()
self.assertEqual(['sda', 'sdb', 'sdc', 'sdd'], result)
# Check we pass the mpath
self.assertIsNone(get_wwn_mock.call_args[0][1])
add_wwid_mock.assert_called_once_with('wwn')
self.assertNotEqual(0, add_path_mock.call_count)
self.assertGreaterEqual(find_dm_mock.call_count, 2)
@ -1238,10 +1240,13 @@ Setting up iSCSI targets: unused
'path': '/dev/dm-0'}
self.assertEqual(expected, res)
self.assertEqual(2, get_wwn_mock.call_count)
self.assertEqual(3, get_wwn_mock.call_count)
result = list(get_wwn_mock.call_args[0][0])
result.sort()
self.assertEqual(['sda', 'sdb', 'sdc', 'sdd'], result)
# Initially mpath we pass is None, but on last call is the mpath
mpath_values = [c[1][1] for c in get_wwn_mock._mock_mock_calls]
self.assertEqual([None, None, 'dm-0'], mpath_values)
add_wwid_mock.assert_not_called()
add_path_mock.assert_not_called()
self.assertGreaterEqual(find_dm_mock.call_count, 2)

View File

@ -860,6 +860,16 @@ loop0 0"""
'id': '0',
'lun': '0'})
@mock.patch('six.moves.builtins.open')
def test_get_sysfs_wwn_mpath(self, open_mock):
wwn = '3600d0230000000000e13955cc3757800'
cm_open = open_mock.return_value.__enter__.return_value
cm_open.read.return_value = 'mpath-' + wwn
res = self.linuxscsi.get_sysfs_wwn(mock.sentinel.device_names, 'dm-1')
open_mock.assert_called_once_with('/sys/block/dm-1/dm/uuid')
self.assertEqual(wwn, res)
@mock.patch('glob.glob')
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
def test_get_sysfs_wwn_single_designator(self, get_wwid_mock, glob_mock):
@ -871,6 +881,20 @@ loop0 0"""
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
get_wwid_mock.assert_called_once_with(mock.sentinel.device_names)
@mock.patch('six.moves.builtins.open', side_effect=Exception)
@mock.patch('glob.glob')
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
def test_get_sysfs_wwn_mpath_exc(self, get_wwid_mock, glob_mock,
open_mock):
glob_mock.return_value = ['/dev/disk/by-id/scsi-wwid1',
'/dev/disk/by-id/scsi-wwid2']
get_wwid_mock.return_value = 'wwid1'
res = self.linuxscsi.get_sysfs_wwn(mock.sentinel.device_names, 'dm-1')
open_mock.assert_called_once_with('/sys/block/dm-1/dm/uuid')
self.assertEqual('wwid1', res)
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
get_wwid_mock.assert_called_once_with(mock.sentinel.device_names)
@mock.patch('os.listdir', return_value=['sda', 'sdd'])
@mock.patch('os.path.realpath', side_effect=('/other/path',
'/dev/dm-5',