FC: Fix multipath wait issue with slow connections
With change[1], we added a mechanism to wait for multipath device to be ready for I/O. see more info in [2]. Sometimes the connection to the storage array is slow and the multipath device doesn't get discovered during the os-brick operation. This leads to failure while waiting for the multipath device where we don't even have the multipath device populated yet in /sys/block/<dev>/holders/dm-* resulting in the following command executing and failing. 'multipath -C None' This does indicate some issue with the connection but we should not fail the operation here since we can still complete it even with a single device discovered. This is already handled in the iSCSI connector[3] with a check for the sysfs dm name being populated or not. This patch adds the same logic to FC where the dm name is not populated but we don't want to fail the operation because of slow connection. Closes-Bug: #2097388 [1] https://review.opendev.org/c/openstack/os-brick/+/920516 [2] https://launchpad.net/bugs/2067949 [3]5f5a8f7563/os_brick/initiator/connectors/iscsi.py (L788-L792)Change-Id: Ie8860d05841cc3222871da55bdddd6b7f8135850 (cherry picked from commit8ac46333d7) (cherry picked from commit557817b9b0) (cherry picked from commitcc7e8ea978)
This commit is contained in:
@@ -290,8 +290,11 @@ class FibreChannelConnector(base.BaseLinuxConnector):
|
||||
device = os.path.basename(self.device_name)
|
||||
mpath = self._linuxscsi.find_sysfs_multipath_dm(
|
||||
[device])
|
||||
# Wait for multipath device to be ready for I/O
|
||||
self._linuxscsi.wait_for_mpath_device(mpath)
|
||||
if mpath:
|
||||
# Sometimes the multipath device doesn't show up
|
||||
# in time and we don't want to fail here.
|
||||
# Wait for multipath device to be ready for I/O
|
||||
self._linuxscsi.wait_for_mpath_device(mpath)
|
||||
else:
|
||||
device_path = self.host_device
|
||||
|
||||
|
||||
@@ -291,7 +291,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
|
||||
connection_info['data'])
|
||||
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device_path')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'wait_for_mpath_device')
|
||||
def _test_connect_volume_multipath(self, get_device_info_mock,
|
||||
get_scsi_wwn_mock,
|
||||
get_fc_hbas_info_mock,
|
||||
@@ -302,7 +301,6 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
|
||||
find_mp_dev_mock,
|
||||
access_mode,
|
||||
should_wait_for_rw,
|
||||
wait_mpath_device_mock,
|
||||
find_mp_device_path_mock):
|
||||
self.connector.use_multipath = True
|
||||
get_fc_hbas_mock.side_effect = self.fake_get_fc_hbas
|
||||
@@ -351,6 +349,49 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
|
||||
self.assertEqual(expected_commands, self.cmds)
|
||||
return connection_info
|
||||
|
||||
@ddt.data(None, 'dm-18')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'wait_for_mpath_device')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_sysfs_multipath_dm')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'wait_for_rw')
|
||||
@mock.patch.object(os.path, 'exists', return_value=True)
|
||||
@mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
|
||||
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
|
||||
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
|
||||
@mock.patch.object(base.BaseLinuxConnector, 'check_valid_device')
|
||||
def test_connect_volume_multipath_found_dm(self, sysfs_dm_name,
|
||||
check_valid_device_mock,
|
||||
get_device_info_mock,
|
||||
get_scsi_wwn_mock,
|
||||
get_fc_hbas_info_mock,
|
||||
get_fc_hbas_mock,
|
||||
realpath_mock,
|
||||
exists_mock,
|
||||
wait_for_rw_mock,
|
||||
find_mp_dev_mock,
|
||||
sysfs_multipath_dm_mock,
|
||||
wait_mpath_device_mock):
|
||||
|
||||
check_valid_device_mock.return_value = True
|
||||
sysfs_multipath_dm_mock.return_value = sysfs_dm_name
|
||||
self._test_connect_volume_multipath(get_device_info_mock,
|
||||
get_scsi_wwn_mock,
|
||||
get_fc_hbas_info_mock,
|
||||
get_fc_hbas_mock,
|
||||
realpath_mock,
|
||||
exists_mock,
|
||||
wait_for_rw_mock,
|
||||
find_mp_dev_mock,
|
||||
'rw',
|
||||
True)
|
||||
sysfs_multipath_dm_mock.assert_called_once()
|
||||
if sysfs_dm_name:
|
||||
wait_mpath_device_mock.assert_called_once_with(sysfs_dm_name)
|
||||
else:
|
||||
wait_mpath_device_mock.assert_not_called()
|
||||
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device')
|
||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'wait_for_rw')
|
||||
@mock.patch.object(os.path, 'exists', return_value=True)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
`Bug #2097388 <https://bugs.launchpad.net/os-brick/+bug/2097388>`_:
|
||||
Fibre Channel: Fixed issue while waiting for multipath device when
|
||||
it is not populated in sysfs.
|
||||
Reference in New Issue
Block a user