Fix FC case sensitive scanning

For FC connections there are multiple places where we check the
initiator target map provided by the backend against the port names of
the HBAs on the system.

Currently this check is case sensitive, but some backends are returning
the port names in the initiator target map upper cased, which usually
results in attach failures.

Some of the reasons for the attach failures is that os-brick will not
issue scan requests.

Example from a 3PAR backend from a specific system:

  Connector properties:
    {
     'wwpns': ['10001409dcd71ff6', '10001409dcd71ff7'],
     'wwnns': ['20001409dcd71ff6', '20001409dcd71ff7'],
     ...
    }

  Connection properties:
    {
     'initiator_target_map': {
       '10001409DCD71FF6': ['20320002AC01E166', '21420002AC01E166'],
       '10001409DCD71FF7': ['20410002AC01E166', '21410002AC01E166']
     }
     ...
    }

This patch converts to lower case the
initiator_target_map and the target_wwn/target_wwns.

Closes-Bug: #1775677
Change-Id: I12b9535d8a9969356394e406a1ed5ac4a5f1f959
(cherry picked from commit 037f9fe667)
Conflicts:
	os_brick/initiator/connectors/fibre_channel.py
This commit is contained in:
Gorka Eguileor 2019-02-19 18:00:22 +01:00
parent 80ee8f846c
commit 00a4d96d25
2 changed files with 45 additions and 3 deletions

View File

@ -83,6 +83,13 @@ class FibreChannelConnector(base.BaseLinuxConnector):
else: else:
wwns = [] wwns = []
# Convert wwns to lower case
wwns = [wwn.lower() for wwn in wwns]
if target_wwns:
connection_properties['target_wwns'] = wwns
elif target_wwn:
connection_properties['target_wwn'] = wwns
target_lun = connection_properties.get('target_lun', 0) target_lun = connection_properties.get('target_lun', 0)
target_luns = connection_properties.get('target_luns') target_luns = connection_properties.get('target_luns')
if target_luns: if target_luns:
@ -116,8 +123,13 @@ class FibreChannelConnector(base.BaseLinuxConnector):
wwpn_lun_map[wwpn] = lun wwpn_lun_map[wwpn] = lun
# If there is an initiator_target_map we can update it too # If there is an initiator_target_map we can update it too
if 'initiator_target_map' in connection_properties: if connection_properties.get('initiator_target_map') is not None:
# Convert it to lower case
itmap = connection_properties['initiator_target_map'] itmap = connection_properties['initiator_target_map']
itmap = {k.lower(): [port.lower() for port in v]
for k, v in itmap.items()}
connection_properties['initiator_target_map'] = itmap
new_itmap = dict() new_itmap = dict()
for init_wwpn in itmap: for init_wwpn in itmap:
target_wwpns = itmap[init_wwpn] target_wwpns = itmap[init_wwpn]
@ -125,7 +137,7 @@ class FibreChannelConnector(base.BaseLinuxConnector):
for target_wwpn in target_wwpns: for target_wwpn in target_wwpns:
if target_wwpn in wwpn_lun_map: if target_wwpn in wwpn_lun_map:
init_targets.append((target_wwpn, init_targets.append((target_wwpn,
wwpn_lun_map[target_wwpn])) wwpn_lun_map[target_wwpn]))
new_itmap[init_wwpn] = init_targets new_itmap[init_wwpn] = init_targets
connection_properties['initiator_target_lun_map'] = new_itmap connection_properties['initiator_target_lun_map'] = new_itmap

View File

@ -591,7 +591,29 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
('1234567890123457', 2)] ('1234567890123457', 2)]
} }
}, },
{
"target_info": {
"target_lun": 1,
"target_wwn": ['20320002AC01E166', '21420002AC01E166',
'20410002AC01E166', '21410002AC01E166']
},
"expected_targets": [
('20320002ac01e166', 1),
('21420002ac01e166', 1),
('20410002ac01e166', 1),
('21410002ac01e166', 1)
],
"itmap": {
'10001409DCD71FF6': ['20320002AC01E166', '21420002AC01E166'],
'10001409DCD71FF7': ['20410002AC01E166', '21410002AC01E166']
},
"expected_map": {
'10001409dcd71ff6': [('20320002ac01e166', 1),
('21420002ac01e166', 1)],
'10001409dcd71ff7': [('20410002ac01e166', 1),
('21410002ac01e166', 1)]
}
},
) )
@ddt.unpack @ddt.unpack
def test__add_targets_to_connection_properties(self, target_info, def test__add_targets_to_connection_properties(self, target_info,
@ -611,6 +633,14 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase):
self.assertIn('targets', connection_info) self.assertIn('targets', connection_info)
self.assertEqual(expected_targets, connection_info['targets']) self.assertEqual(expected_targets, connection_info['targets'])
# Check that we turn to lowercase target wwns
key = 'target_wwns' if 'target_wwns' in target_info else 'target_wwn'
wwns = target_info.get(key)
wwns = [wwns] if isinstance(wwns, six.string_types) else wwns
wwns = [w.lower() for w in wwns]
if wwns:
self.assertEqual(wwns, conn['data'][key])
if itmap: if itmap:
self.assertIn('initiator_target_lun_map', connection_info) self.assertIn('initiator_target_lun_map', connection_info)
self.assertEqual(expected_map, self.assertEqual(expected_map,