Merge "Improve WWN detection" into stable/train

This commit is contained in:
Zuul 2020-08-30 09:06:50 +00:00 committed by Gerrit Code Review
commit 2300733ff5
3 changed files with 68 additions and 7 deletions

View File

@ -128,16 +128,34 @@ class LinuxSCSI(executor.Executor):
if wwid and glob_str + wwid in wwn_paths:
return wwid
# If we have multiple designators follow the symlinks
# If we have multiple designators use symlinks to find out the wwn
device_names = set(device_names)
for wwn_path in wwn_paths:
try:
if os.path.islink(wwn_path) and os.stat(wwn_path):
path = os.path.realpath(wwn_path)
if path.startswith('/dev/') and path[5:] in device_names:
return wwn_path[len(glob_str):]
if path.startswith('/dev/'):
name = path[5:]
# Symlink may point to the multipath dm if the attach
# was too fast or we took long to check it. Check
# devices belonging to the multipath DM.
if name.startswith('dm-'):
# Get the devices that belong to the DM
slaves_path = '/sys/class/block/%s/slaves' % name
dm_devs = os.listdir(slaves_path)
# This is the right wwn_path if the devices we have
# attached belong to the dm we followed
if device_names.intersection(dm_devs):
break
# This is the right wwn_path if devices we have
elif name in device_names:
break
except OSError:
continue
return ''
else:
return ''
return wwn_path[len(glob_str):]
def get_sysfs_wwid(self, device_names):
"""Return the wwid from sysfs in any of devices in udev format."""

View File

@ -859,25 +859,53 @@ 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('os.listdir', return_value=['sda', 'sdd'])
@mock.patch('os.path.realpath', side_effect=('/other/path',
'/dev/dm-5',
'/dev/sda', '/dev/sdb'))
@mock.patch('os.path.islink', side_effect=(False, True, True, True, True))
@mock.patch('os.stat', side_effect=(False, True, True, True))
@mock.patch('os.path.islink', side_effect=(False,) + (True,) * 5)
@mock.patch('os.stat', side_effect=(False,) + (True,) * 4)
@mock.patch('glob.glob')
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
def test_get_sysfs_wwn_multiple_designators(self, get_wwid_mock, glob_mock,
stat_mock, islink_mock,
realpath_mock):
realpath_mock, listdir_mock):
glob_mock.return_value = ['/dev/disk/by-id/scsi-fail-link',
'/dev/disk/by-id/scsi-fail-stat',
'/dev/disk/by-id/scsi-non-dev',
'/dev/disk/by-id/scsi-another-dm',
'/dev/disk/by-id/scsi-wwid1',
'/dev/disk/by-id/scsi-wwid2']
get_wwid_mock.return_value = 'pre-wwid'
devices = ['sdb', 'sdc']
res = self.linuxscsi.get_sysfs_wwn(devices)
self.assertEqual('wwid2', res)
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
listdir_mock.assert_called_once_with('/sys/class/block/dm-5/slaves')
get_wwid_mock.assert_called_once_with(devices)
@mock.patch('os.listdir', side_effect=[['sda', 'sdb'], ['sdc', 'sdd']])
@mock.patch('os.path.realpath', side_effect=('/dev/sde',
'/dev/dm-5',
'/dev/dm-6'))
@mock.patch('os.path.islink', mock.Mock())
@mock.patch('os.stat', mock.Mock())
@mock.patch('glob.glob')
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid', return_value='')
def test_get_sysfs_wwn_dm_link(self, get_wwid_mock, glob_mock,
realpath_mock, listdir_mock):
glob_mock.return_value = ['/dev/disk/by-id/scsi-wwid1',
'/dev/disk/by-id/scsi-another-dm',
'/dev/disk/by-id/scsi-our-dm']
devices = ['sdc', 'sdd']
res = self.linuxscsi.get_sysfs_wwn(devices)
self.assertEqual('our-dm', res)
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
listdir_mock.assert_has_calls(
[mock.call('/sys/class/block/dm-5/slaves'),
mock.call('/sys/class/block/dm-6/slaves')])
get_wwid_mock.assert_called_once_with(devices)
@mock.patch('os.path.realpath', side_effect=('/dev/sda', '/dev/sdb'))
@ -896,6 +924,16 @@ loop0 0"""
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
get_wwid_mock.assert_called_once_with(devices)
@mock.patch('glob.glob', return_value=[])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_sysfs_wwid')
def test_get_sysfs_wwn_no_links(self, get_wwid_mock, glob_mock):
get_wwid_mock.return_value = ''
devices = ['sdc']
res = self.linuxscsi.get_sysfs_wwn(devices)
self.assertEqual('', res)
glob_mock.assert_called_once_with('/dev/disk/by-id/scsi-*')
get_wwid_mock.assert_called_once_with(devices)
@ddt.data({'wwn_type': 't10.', 'num_val': '1'},
{'wwn_type': 'eui.', 'num_val': '2'},
{'wwn_type': 'naa.', 'num_val': '3'})

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Improve WWN detection for arrays with multiple designators.
(bug 1881608).