Leverage the iSCSI mpath to get the WWN
Now that we search the multipath device even if we haven't been able to find the WWN in the sysfs we can leverage the multipath daemon information on sysfs to get the WWN. Pass the mpath to "get_sysfs_wwn" method where we check the sysfs to get the WWN. Conflicts: os_brick/tests/initiator/connectors/test_iscsi.py os_brick/tests/initiator/test_linuxscsi.py The tests required a few fixes to account for the differences between the branches and the changes introduced by the backports this one builds upon. Change-Id: Id1905bc174b8f2f3a345664d8a0a05284ca69927 (cherry picked from commit0cdd9bbbe2
) (cherry picked from commit31c01b543c
)
This commit is contained in:
parent
57ac89910e
commit
609f0bcf83
@ -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)
|
||||
|
||||
|
@ -119,8 +119,20 @@ class LinuxSCSI(executor.Executor):
|
||||
|
||||
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 + '*')
|
||||
|
@ -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.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.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[0:3])
|
||||
add_wwid_mock.assert_not_called()
|
||||
add_path_mock.assert_not_called()
|
||||
self.assertGreaterEqual(find_dm_mock.call_count, 2)
|
||||
|
@ -848,6 +848,16 @@ loop0 0"""
|
||||
mock_exec.assert_called_once_with(
|
||||
'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.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
|
||||
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-*')
|
||||
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',
|
||||
|
Loading…
Reference in New Issue
Block a user