Merge "Leverage the iSCSI mpath to get the WWN" into stable/train

This commit is contained in:
Zuul 2020-09-02 21:41:27 +00:00 committed by Gerrit Code Review
commit 634fb4a9aa
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'])): data['failed_logins'])):
# We have devices but we don't know the wwn yet # We have devices but we don't know the wwn yet
if not wwn and found: 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: if not mpath and found:
mpath = self._linuxscsi.find_sysfs_multipath_dm(found) mpath = self._linuxscsi.find_sysfs_multipath_dm(found)
# We have the wwn but not a multipath # We have the wwn but not a multipath
@ -778,6 +778,8 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
if not mpath: if not mpath:
LOG.warning('No dm was created, connection to volume is probably ' LOG.warning('No dm was created, connection to volume is probably '
'bad and will perform poorly.') '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, return self._get_connect_result(connection_properties, wwn, found,
mpath) mpath)

View File

@ -119,8 +119,20 @@ class LinuxSCSI(executor.Executor):
return 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.""" """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) wwid = self.get_sysfs_wwid(device_names)
glob_str = '/dev/disk/by-id/scsi-' glob_str = '/dev/disk/by-id/scsi-'
wwn_paths = glob.glob(glob_str + '*') 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 = list(get_wwn_mock.call_args[0][0])
result.sort() result.sort()
self.assertEqual(['sda', 'sdb', 'sdc', 'sdd'], result) 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') add_wwid_mock.assert_called_once_with('wwn')
self.assertNotEqual(0, add_path_mock.call_count) self.assertNotEqual(0, add_path_mock.call_count)
self.assertGreaterEqual(find_dm_mock.call_count, 2) self.assertGreaterEqual(find_dm_mock.call_count, 2)
@ -1238,10 +1240,13 @@ Setting up iSCSI targets: unused
'path': '/dev/dm-0'} 'path': '/dev/dm-0'}
self.assertEqual(expected, res) self.assertEqual(expected, res)
self.assertGreaterEqual(get_wwn_mock.call_count, 2) self.assertGreaterEqual(get_wwn_mock.call_count, 3)
result = list(get_wwn_mock.call_args[0][0]) result = list(get_wwn_mock.call_args[0][0])
result.sort() result.sort()
self.assertEqual(['sda', 'sdb', 'sdc', 'sdd'], result) 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[0:3])
add_wwid_mock.assert_not_called() add_wwid_mock.assert_not_called()
add_path_mock.assert_not_called() add_path_mock.assert_not_called()
self.assertGreaterEqual(find_dm_mock.call_count, 2) self.assertGreaterEqual(find_dm_mock.call_count, 2)

View File

@ -848,6 +848,16 @@ loop0 0"""
mock_exec.assert_called_once_with( mock_exec.assert_called_once_with(
'multipathd', 'show', 'status', run_as_root=True, root_helper=None) 'multipathd', 'show', 'status', run_as_root=True, root_helper=None)
@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('glob.glob')
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid') @mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
def test_get_sysfs_wwn_single_designator(self, get_wwid_mock, glob_mock): def test_get_sysfs_wwn_single_designator(self, get_wwid_mock, glob_mock):
@ -859,6 +869,20 @@ loop0 0"""
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*') glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
get_wwid_mock.assert_called_once_with(mock.sentinel.device_names) 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.listdir', return_value=['sda', 'sdd'])
@mock.patch('os.path.realpath', side_effect=('/other/path', @mock.patch('os.path.realpath', side_effect=('/other/path',
'/dev/dm-5', '/dev/dm-5',