FC: Ignore some HBAs from map for single WWNN

Current FC OS-Brick code only checks for single WWNN to exclude some
HBAs from scanning when we don't receive an initiator_target_map from
the backend.

There are storage arrays,like XtremIO, that due to their architecture
and design have all target ports automatically mapped to LUNs and are
returning the initiator_target_map, but some of those ports may not be
connected to our HBAs, so we end up with another case of bug #1765000.

This patch makes sure that we always check if the target implements
single WWNN, not only when we don't receive the initiator_target_map.

With this we decrease the likelihood of ending with unexpected devices
in our system, because now we will ignore unconnected HBAs (even if
reported in the initiator_target_map) if we are working with single WWNN
target.

Related-Bug: #1765000
Closes-Bug: #1828440
Change-Id: I02c208142f5b342f894666831449243863eccbfe
(cherry picked from commit 70899a9aa3)
(cherry picked from commit 1ee6acb509)
This commit is contained in:
Gorka Eguileor 2019-05-09 17:25:03 +02:00 committed by Keigo Noha
parent bdd05d2232
commit 66d9d2a908
3 changed files with 56 additions and 19 deletions

View File

@ -89,13 +89,13 @@ class LinuxFibreChannel(linuxscsi.LinuxSCSI):
if ports:
hbas = [hba for hba in hbas if hba['port_name'] in ports]
LOG.debug('Using initiator target map to exclude HBAs')
process = [(hba, get_ctsl(hba, connection_properties))
for hba in hbas]
# With no target map we'll check if target implements single WWNN for
# all ports, if it does we only use HBAs connected (info was found),
# otherwise we are forced to blindly scan all HBAs.
else:
# Check if target implements single WWNN for all ports, if it does we
# only use HBAs connected (info was found), otherwise we are forced to
# blindly scan all HBAs. We also do this when we have
# initiator_target_map, because some drivers return all HBAs but they
# implement single WWNN and we avoid adding unrelated LUNs this way
# (LP bug#1765000).
with_info = []
no_info = []

View File

@ -260,6 +260,33 @@ class LinuxFCTestCase(base.TestCase):
mock.call(hbas[1], con_props)]
mock_get_chan.assert_has_calls(expected_calls)
def test_rescan_hosts_initiator_map_single_wwnn(self):
"""Test FC rescan with initiator map and single WWNN."""
get_chan_results = [[['2', '3', 1], ['4', '5', 1]], [['-', '-', 1]]]
hbas, con_props = self.__get_rescan_info(zone_manager=True)
with mock.patch.object(self.lfc, '_execute',
return_value=None) as execute_mock, \
mock.patch.object(self.lfc, '_get_hba_channel_scsi_target',
side_effect=get_chan_results) as mock_get_chan:
self.lfc.rescan_hosts(hbas, con_props)
expected_commands = [
mock.call('tee', '-a', '/sys/class/scsi_host/host6/scan',
process_input='2 3 1',
root_helper=None, run_as_root=True),
mock.call('tee', '-a', '/sys/class/scsi_host/host6/scan',
process_input='4 5 1',
root_helper=None, run_as_root=True)]
execute_mock.assert_has_calls(expected_commands)
self.assertEqual(len(expected_commands), execute_mock.call_count)
expected_calls = [mock.call(hbas[0], con_props),
mock.call(hbas[1], con_props)]
mock_get_chan.assert_has_calls(expected_calls)
def test_rescan_hosts_wildcard(self):
"""Test when we don't have initiator map or target is single WWNN."""
get_chan_results = [[['-', '-', 1]], [['-', '-', 1]]]

View File

@ -0,0 +1,10 @@
---
fixes:
- |
Always check if we are dealing with a single WWNN Fibre Channel target,
even when we receive an initiator_target_map.
This allows us to exclude unconnected HBAs from our scan for storage arrays
that automatically connect all target ports (due to their architecture and
design) even if the Cinder driver returns the initiator_target_map,
provided the target has a single WWNN.
Excluding these HBAs prevents undesired volumes from being connected.