Merge "Improve WWN detection"
This commit is contained in:
commit
d1e978e6ea
|
@ -136,16 +136,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."""
|
||||
|
|
|
@ -871,25 +871,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'))
|
||||
|
@ -908,6 +936,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'})
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Improve WWN detection for arrays with multiple designators.
|
||||
(bug 1881608).
|
Loading…
Reference in New Issue