linuxscsi: Stop waiting for multipath devices during extend_volume

Previously linuxscsi.extend_volume would always attempt to wait for
multipath devices to appear regardless of multipath actually being used
by the connector.

This change corrects this by passing down the existing use_multipath
attribute from the iSCSI and FC connectors into linuxscsi.extend_volume.
The same attribute is introduced to the NVMe connector to also allow it
to skip this search for multipath devices.

Change-Id: I29d65ae036957f3a63cba93dd330b14e3361a1b9
Closes-bug: #1832247
This commit is contained in:
Lee Yarwood 2019-06-10 19:02:19 +01:00
parent 94312bd90f
commit 9cf135c686
6 changed files with 37 additions and 25 deletions

View File

@ -176,7 +176,8 @@ class FibreChannelConnector(base.BaseLinuxConnector):
volume_paths = self.get_volume_paths(connection_properties) volume_paths = self.get_volume_paths(connection_properties)
if volume_paths: if volume_paths:
return self._linuxscsi.extend_volume(volume_paths) return self._linuxscsi.extend_volume(
volume_paths, use_multipath=self.use_multipath)
else: else:
LOG.warning("Couldn't find any volume paths on the host to " LOG.warning("Couldn't find any volume paths on the host to "
"extend volume for %(props)s", "extend volume for %(props)s",

View File

@ -474,7 +474,8 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
volume_paths = self.get_volume_paths(connection_properties) volume_paths = self.get_volume_paths(connection_properties)
LOG.info("Found paths for volume %s", volume_paths) LOG.info("Found paths for volume %s", volume_paths)
if volume_paths: if volume_paths:
return self._linuxscsi.extend_volume(volume_paths) return self._linuxscsi.extend_volume(
volume_paths, use_multipath=self.use_multipath)
else: else:
LOG.warning("Couldn't find any volume paths on the host to " LOG.warning("Couldn't find any volume paths on the host to "
"extend volume for %(props)s", "extend volume for %(props)s",

View File

@ -34,7 +34,7 @@ class NVMeConnector(base.BaseLinuxConnector):
"""Connector class to attach/detach NVMe over fabric volumes.""" """Connector class to attach/detach NVMe over fabric volumes."""
def __init__(self, root_helper, driver=None, def __init__(self, root_helper, driver=None, use_multipath=False,
device_scan_attempts=DEVICE_SCAN_ATTEMPTS_DEFAULT, device_scan_attempts=DEVICE_SCAN_ATTEMPTS_DEFAULT,
*args, **kwargs): *args, **kwargs):
super(NVMeConnector, self).__init__( super(NVMeConnector, self).__init__(
@ -42,6 +42,7 @@ class NVMeConnector(base.BaseLinuxConnector):
driver=driver, driver=driver,
device_scan_attempts=device_scan_attempts, device_scan_attempts=device_scan_attempts,
*args, **kwargs) *args, **kwargs)
self.use_multipath = use_multipath
def _get_system_uuid(self): def _get_system_uuid(self):
# RSD requires system_uuid to let Cinder RSD Driver identify # RSD requires system_uuid to let Cinder RSD Driver identify
@ -226,7 +227,8 @@ class NVMeConnector(base.BaseLinuxConnector):
""" """
volume_paths = self.get_volume_paths(connection_properties) volume_paths = self.get_volume_paths(connection_properties)
if volume_paths: if volume_paths:
return self._linuxscsi.extend_volume(volume_paths) return self._linuxscsi.extend_volume(
volume_paths, use_multipath=self.use_multipath)
else: else:
LOG.warning("Couldn't find any volume paths on the host to " LOG.warning("Couldn't find any volume paths on the host to "
"extend volume for %(props)s", "extend volume for %(props)s",

View File

@ -531,7 +531,7 @@ class LinuxSCSI(executor.Executor):
root_helper=self._root_helper) root_helper=self._root_helper)
return out return out
def extend_volume(self, volume_paths): def extend_volume(self, volume_paths, use_multipath=False):
"""Signal the SCSI subsystem to test for volume resize. """Signal the SCSI subsystem to test for volume resize.
This function tries to signal the local system's kernel This function tries to signal the local system's kernel
@ -561,24 +561,26 @@ class LinuxSCSI(executor.Executor):
LOG.debug("volume size after scsi device rescan %s", new_size) LOG.debug("volume size after scsi device rescan %s", new_size)
scsi_wwn = self.get_scsi_wwn(volume_paths[0]) scsi_wwn = self.get_scsi_wwn(volume_paths[0])
mpath_device = self.find_multipath_device_path(scsi_wwn) if use_multipath:
if mpath_device: mpath_device = self.find_multipath_device_path(scsi_wwn)
# Force a reconfigure so that resize works if mpath_device:
self.multipath_reconfigure() # Force a reconfigure so that resize works
self.multipath_reconfigure()
size = self.get_device_size(mpath_device) size = self.get_device_size(mpath_device)
LOG.info("mpath(%(device)s) current size %(size)s", LOG.info("mpath(%(device)s) current size %(size)s",
{'device': mpath_device, 'size': size}) {'device': mpath_device, 'size': size})
result = self.multipath_resize_map(scsi_wwn) result = self.multipath_resize_map(scsi_wwn)
if 'fail' in result: if 'fail' in result:
LOG.error("Multipathd failed to update the size mapping of " LOG.error("Multipathd failed to update the size mapping "
"multipath device %(scsi_wwn)s volume %(volume)s", "of multipath device %(scsi_wwn)s volume "
{'scsi_wwn': scsi_wwn, 'volume': volume_paths}) "%(volume)s",
return None {'scsi_wwn': scsi_wwn, 'volume': volume_paths})
return None
new_size = self.get_device_size(mpath_device) new_size = self.get_device_size(mpath_device)
LOG.info("mpath(%(device)s) new size %(size)s", LOG.info("mpath(%(device)s) new size %(size)s",
{'device': mpath_device, 'size': new_size}) {'device': mpath_device, 'size': new_size})
return new_size return new_size

View File

@ -38,7 +38,8 @@ class NVMeConnectorTestCase(test_connector.ConnectorTestCase):
def setUp(self): def setUp(self):
super(NVMeConnectorTestCase, self).setUp() super(NVMeConnectorTestCase, self).setUp()
self.connector = nvme.NVMeConnector(None, self.connector = nvme.NVMeConnector(None,
execute=self.fake_execute) execute=self.fake_execute,
use_multipath=False)
@mock.patch.object(nvme.NVMeConnector, '_execute') @mock.patch.object(nvme.NVMeConnector, '_execute')
def test_get_sysuuid_without_newline(self, mock_execute): def test_get_sysuuid_without_newline(self, mock_execute):
@ -284,9 +285,11 @@ class NVMeConnectorTestCase(test_connector.ConnectorTestCase):
self.connector.extend_volume, self.connector.extend_volume,
connection_properties) connection_properties)
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device_path')
@mock.patch.object(linuxscsi.LinuxSCSI, 'extend_volume') @mock.patch.object(linuxscsi.LinuxSCSI, 'extend_volume')
@mock.patch.object(nvme.NVMeConnector, 'get_volume_paths') @mock.patch.object(nvme.NVMeConnector, 'get_volume_paths')
def test_extend_volume(self, mock_volume_paths, mock_scsi_extend): def test_extend_volume(self, mock_volume_paths, mock_scsi_extend,
mock_scsi_find_mpath):
fake_new_size = 1024 fake_new_size = 1024
mock_volume_paths.return_value = ['/dev/vdx'] mock_volume_paths.return_value = ['/dev/vdx']
mock_scsi_extend.return_value = fake_new_size mock_scsi_extend.return_value = fake_new_size
@ -297,3 +300,4 @@ class NVMeConnectorTestCase(test_connector.ConnectorTestCase):
'transport_type': 'rdma'} 'transport_type': 'rdma'}
new_size = self.connector.extend_volume(connection_properties) new_size = self.connector.extend_volume(connection_properties)
self.assertEqual(fake_new_size, new_size) self.assertEqual(fake_new_size, new_size)
mock_scsi_find_mpath.assert_not_called()

View File

@ -761,7 +761,8 @@ loop0 0"""
mock_find_mpath_path.return_value = ('/dev/mapper/dm-uuid-mpath-%s' % mock_find_mpath_path.return_value = ('/dev/mapper/dm-uuid-mpath-%s' %
wwn) wwn)
ret_size = self.linuxscsi.extend_volume(['/dev/fake1', '/dev/fake2']) ret_size = self.linuxscsi.extend_volume(['/dev/fake1', '/dev/fake2'],
use_multipath=True)
self.assertEqual(2048, ret_size) self.assertEqual(2048, ret_size)
# because we don't mock out the echo_scsi_command # because we don't mock out the echo_scsi_command
@ -795,7 +796,8 @@ loop0 0"""
mock_mpath_resize_map.return_value = 'fail' mock_mpath_resize_map.return_value = 'fail'
ret_size = self.linuxscsi.extend_volume(['/dev/fake1', '/dev/fake2']) ret_size = self.linuxscsi.extend_volume(['/dev/fake1', '/dev/fake2'],
use_multipath=True)
self.assertIsNone(ret_size) self.assertIsNone(ret_size)
# because we don't mock out the echo_scsi_command # because we don't mock out the echo_scsi_command