Browse Source

Fix multipath flush when using friendly names

When we are using friendly names for multipath the multipaths are not
getting flushed, which may lead to data loss on slow connections and
multipath entries with no actual paths.

This happens in both iSCSI and FC connections, and it is due to the
flush being requested on the WWN instead of the actual name of the
device.

So when we are not using friendly names the WWN and the device name are
the same and our call to multipath -f will successfully flush remaining
data, but when we are using friendly names they will not match, and the
call to multipath -f will silently fail (return code 0) and the flush
will not actually go through. When the flush doesn't happen, if there is
remaining data, then the multipath will stay once the individual paths
have been removed.

Closes-Bug: #1663925
Change-Id: Ib93d945a5b5fca57bcac4e176d62d1412b95f2da
changes/02/433102/3
Gorka Eguileor 6 years ago
parent
commit
c0640ce137
  1. 14
      os_brick/initiator/connectors/fibre_channel.py
  2. 2
      os_brick/initiator/linuxscsi.py
  3. 11
      os_brick/tests/initiator/connectors/test_fibre_channel.py
  4. 3
      os_brick/tests/initiator/test_linuxscsi.py

14
os_brick/initiator/connectors/fibre_channel.py

@ -260,21 +260,19 @@ class FibreChannelConnector(base.BaseLinuxConnector):
"""
devices = []
volume_paths = self.get_volume_paths(connection_properties)
wwn = None
volume_paths = self.get_volume_paths(connection_properties)
mpath_path = None
for path in volume_paths:
real_path = self._linuxscsi.get_name_from_path(path)
if not wwn:
if self.use_multipath and not mpath_path:
wwn = self._linuxscsi.get_scsi_wwn(path)
mpath_path = self._linuxscsi.find_multipath_device_path(wwn)
if mpath_path:
self._linuxscsi.flush_multipath_device(mpath_path)
device_info = self._linuxscsi.get_device_info(real_path)
devices.append(device_info)
if self.use_multipath:
# There is a bug in multipath where the flushing
# doesn't remove the entry if friendly names are on
# we'll try anyway.
self._linuxscsi.flush_multipath_device(wwn)
LOG.debug("devices to remove = %s", devices)
self._remove_devices(connection_properties, devices)

2
os_brick/initiator/linuxscsi.py

@ -134,7 +134,7 @@ class LinuxSCSI(executor.Executor):
LOG.debug("remove multipath device %s", device)
mpath_dev = self.find_multipath_device(device)
if mpath_dev:
self.flush_multipath_device(mpath_dev['id'])
self.flush_multipath_device(mpath_dev['name'])
devices = mpath_dev['devices']
LOG.debug("multipath LUNs to remove %s", devices)
for device in devices:

11
os_brick/tests/initiator/connectors/test_fibre_channel.py

@ -193,6 +193,7 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
self.connector.connect_volume,
connection_info['data'])
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device_path')
def _test_connect_volume_multipath(self, get_device_info_mock,
get_scsi_wwn_mock,
get_fc_hbas_info_mock,
@ -202,7 +203,8 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
wait_for_rw_mock,
find_mp_dev_mock,
access_mode,
should_wait_for_rw):
should_wait_for_rw,
find_mp_device_path_mock):
self.connector.use_multipath = True
get_fc_hbas_mock.side_effect = self.fake_get_fc_hbas
get_fc_hbas_info_mock.side_effect = self.fake_get_fc_hbas_info
@ -227,7 +229,10 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
vol = {'id': 1, 'name': name}
initiator_wwn = ['1234567890123456', '1234567890123457']
find_mp_dev_mock.return_value = '/dev/disk/by-id/dm-uuid-mpath-' + wwn
find_mp_device_path_mock.return_value = '/dev/mapper/mpatha'
find_mp_dev_mock.return_value = {"device": "dm-3",
"id": wwn,
"name": "mpatha"}
connection_info = self.fibrechan_connection(vol, location,
initiator_wwn)
@ -240,7 +245,7 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
self.connector.disconnect_volume(connection_info['data'],
devices['devices'][0])
expected_commands = [
'multipath -f ' + wwn,
'multipath -f ' + find_mp_device_path_mock.return_value,
'blockdev --flushbufs /dev/sdb',
'tee -a /sys/block/sdb/device/delete',
'blockdev --flushbufs /dev/sdc',

3
os_brick/tests/initiator/test_linuxscsi.py

@ -161,6 +161,7 @@ class LinuxSCSITestCase(base.TestCase):
info = {"device": "dm-3",
"id": "350002ac20398383d",
"name": "mpatha",
"devices": devices}
return info
@ -168,7 +169,7 @@ class LinuxSCSITestCase(base.TestCase):
self.linuxscsi.remove_multipath_device('/dev/dm-3')
expected_commands = [
('multipath -f 350002ac20398383d'),
('multipath -f mpatha'),
('blockdev --flushbufs /dev/sde'),
('tee -a /sys/block/sde/device/delete'),
('blockdev --flushbufs /dev/sdf'),

Loading…
Cancel
Save