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. Change-Id: Id1905bc174b8f2f3a345664d8a0a05284ca69927
This commit is contained in:
parent
6974808cb5
commit
0cdd9bbbe2
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 + '*')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue