diff --git a/os_brick/initiator/connectors/fibre_channel.py b/os_brick/initiator/connectors/fibre_channel.py index 9f736b168..0e70f614c 100644 --- a/os_brick/initiator/connectors/fibre_channel.py +++ b/os_brick/initiator/connectors/fibre_channel.py @@ -270,12 +270,13 @@ class FibreChannelConnector(base.BaseLinuxConnector): def _get_host_devices(self, possible_devs): """Compute the device paths on the system with an id, wwn, and lun - :param possible_devs: list of (pci_id, wwn, lun) tuples + :param possible_devs: list of (platform, pci_id, wwn, lun) tuples :return: list of device paths on the system based on the possible_devs """ host_devices = [] - for pci_num, target_wwn, lun in possible_devs: - host_device = "/dev/disk/by-path/pci-%s-fc-%s-lun-%s" % ( + for platform, pci_num, target_wwn, lun in possible_devs: + host_device = "/dev/disk/by-path/%spci-%s-fc-%s-lun-%s" % ( + platform + '-' if platform else '', pci_num, target_wwn, self._linuxscsi.process_lun_id(lun)) @@ -288,7 +289,7 @@ class FibreChannelConnector(base.BaseLinuxConnector): :param hbas: available hba devices. :param targets: tuple of possible wwn addresses and lun combinations. - :returns: list of (pci_id, wwn, lun) tuples + :returns: list of (platform, pci_id, wwn, lun) tuples Given one or more wwn (mac addresses for fibre channel) ports do the matrix math to figure out a set of pci device, wwn @@ -298,11 +299,11 @@ class FibreChannelConnector(base.BaseLinuxConnector): """ raw_devices = [] for hba in hbas: - pci_num = self._get_pci_num(hba) + platform, pci_num = self._get_pci_num(hba) if pci_num is not None: for wwn, lun in targets: target_wwn = "0x%s" % wwn.lower() - raw_devices.append((pci_num, target_wwn, lun)) + raw_devices.append((platform, pci_num, target_wwn, lun)) return raw_devices @utils.trace @@ -365,10 +366,18 @@ class FibreChannelConnector(base.BaseLinuxConnector): # /sys/devices/pci0000:20/0000:20:03.0/0000:21:00.2/net/ens2f2/ctlr_2 # /host3/fc_host/host3 # we always want the value prior to the host or net value + # on non x86_64 device, pci devices may be appended on platform device, + # /sys/devices/platform/smb/smb:motherboard/80040000000.peu0-c0/pci0000:00/0000:00:03.0/0000:05:00.3/host2/fc_host/host2 # noqa + # so also return a platform id if it exists + platform = None if hba is not None: if "device_path" in hba: device_path = hba['device_path'].split('/') + has_platform = (len(device_path) > 3 + and device_path[3] == 'platform') for index, value in enumerate(device_path): + if has_platform and value.startswith('pci'): + platform = "platform-%s" % device_path[index - 1] if value.startswith('net') or value.startswith('host'): - return device_path[index - 1] - return None + return platform, device_path[index - 1] + return None, None diff --git a/os_brick/initiator/connectors/fibre_channel_s390x.py b/os_brick/initiator/connectors/fibre_channel_s390x.py index f30b2123f..4fb4eb934 100644 --- a/os_brick/initiator/connectors/fibre_channel_s390x.py +++ b/os_brick/initiator/connectors/fibre_channel_s390x.py @@ -91,7 +91,7 @@ class FibreChannelConnectorS390X(fibre_channel.FibreChannelConnector): hbas = self._linuxfc.get_fc_hbas_info() targets = connection_properties['targets'] possible_devs = self._get_possible_devices(hbas, targets) - for pci_num, target_wwn, lun in possible_devs: + for platform, pci_num, target_wwn, lun in possible_devs: target_lun = self._get_lun_string(lun) self._linuxfc.deconfigure_scsi_device(pci_num, target_wwn, diff --git a/os_brick/tests/initiator/connectors/test_fibre_channel.py b/os_brick/tests/initiator/connectors/test_fibre_channel.py index 475b54a4c..7a01c6bee 100644 --- a/os_brick/tests/initiator/connectors/test_fibre_channel.py +++ b/os_brick/tests/initiator/connectors/test_fibre_channel.py @@ -60,6 +60,32 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase): 'vport_create': '', 'vport_delete': ''}] + def fake_get_fc_hbas_with_platform(self): + return [{'ClassDevice': 'host1', + 'ClassDevicePath': '/sys/devices/platform/smb' + '/smb:motherboard/80040000000.peu0-c0' + '/pci0000:00/0000:00:03.0' + '/0000:05:00.2/host1/fc_host/host1', + 'dev_loss_tmo': '30', + 'fabric_name': '0x1000000533f55566', + 'issue_lip': '', + 'max_npiv_vports': '255', + 'maxframe_size': '2048 bytes', + 'node_name': '0x200010604b019419', + 'npiv_vports_inuse': '0', + 'port_id': '0x680409', + 'port_name': '0x100010604b019419', + 'port_state': 'Online', + 'port_type': 'NPort (fabric via point-to-point)', + 'speed': '10 Gbit', + 'supported_classes': 'Class 3', + 'supported_speeds': '10 Gbit', + 'symbolic_name': 'Emulex 554M FV4.0.493.0 DV8.3.27', + 'tgtid_bind_type': 'wwpn (World Wide Port Name)', + 'uevent': None, + 'vport_create': '', + 'vport_delete': ''}] + def fake_get_fc_hbas_info(self): hbas = self.fake_get_fc_hbas() info = [{'port_name': hbas[0]['port_name'].replace('0x', ''), @@ -68,6 +94,14 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase): 'device_path': hbas[0]['ClassDevicePath']}] return info + def fake_get_fc_hbas_info_with_platform(self): + hbas = self.fake_get_fc_hbas_with_platform() + info = [{'port_name': hbas[0]['port_name'].replace('0x', ''), + 'node_name': hbas[0]['node_name'].replace('0x', ''), + 'host_device': hbas[0]['ClassDevice'], + 'device_path': hbas[0]['ClassDevicePath']}] + return info + def fibrechan_connection(self, volume, location, wwn, lun=1): return {'driver_volume_type': 'fibrechan', 'data': { @@ -99,19 +133,45 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase): def test_get_pci_num(self): hba = {'device_path': "/sys/devices/pci0000:00/0000:00:03.0" "/0000:05:00.3/host2/fc_host/host2"} - pci_num = self.connector._get_pci_num(hba) + platform, pci_num = self.connector._get_pci_num(hba) self.assertEqual("0000:05:00.3", pci_num) + self.assertIsNone(platform) hba = {'device_path': "/sys/devices/pci0000:00/0000:00:03.0" "/0000:05:00.3/0000:06:00.6/host2/fc_host/host2"} - pci_num = self.connector._get_pci_num(hba) + platform, pci_num = self.connector._get_pci_num(hba) self.assertEqual("0000:06:00.6", pci_num) + self.assertIsNone(platform) hba = {'device_path': "/sys/devices/pci0000:20/0000:20:03.0" "/0000:21:00.2/net/ens2f2/ctlr_2/host3" "/fc_host/host3"} - pci_num = self.connector._get_pci_num(hba) + platform, pci_num = self.connector._get_pci_num(hba) self.assertEqual("0000:21:00.2", pci_num) + self.assertIsNone(platform) + + def test_get_pci_num_with_platform(self): + hba = {'device_path': "/sys/devices/platform/smb/smb:motherboard/" + "80040000000.peu0-c0/pci0000:00/0000:00:03.0" + "/0000:05:00.3/host2/fc_host/host2"} + platform, pci_num = self.connector._get_pci_num(hba) + self.assertEqual("0000:05:00.3", pci_num) + self.assertEqual("platform-80040000000.peu0-c0", platform) + + hba = {'device_path': "/sys/devices/platform/smb/smb:motherboard" + "/80040000000.peu0-c0/pci0000:00/0000:00:03.0" + "/0000:05:00.3/0000:06:00.6/host2/fc_host/host2"} + platform, pci_num = self.connector._get_pci_num(hba) + self.assertEqual("0000:06:00.6", pci_num) + self.assertEqual("platform-80040000000.peu0-c0", platform) + + hba = {'device_path': "/sys/devices/platform/smb" + "/smb:motherboard/80040000000.peu0-c0/pci0000:20" + "/0000:20:03.0/0000:21:00.2" + "/net/ens2f2/ctlr_2/host3/fc_host/host3"} + platform, pci_num = self.connector._get_pci_num(hba) + self.assertEqual("0000:21:00.2", pci_num) + self.assertEqual("platform-80040000000.peu0-c0", platform) @mock.patch.object(os.path, 'exists', return_value=True) @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas') @@ -135,6 +195,30 @@ class FibreChannelConnectorTestCase(test_connector.ConnectorTestCase): '-fc-0x1234567890123456-lun-1'] self.assertEqual(expected, volume_paths) + @mock.patch.object(os.path, 'exists', return_value=True) + @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas') + @mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info') + def test_get_volume_paths_with_platform(self, fake_fc_hbas_info, + fake_fc_hbas, fake_exists): + fake_fc_hbas.side_effect = self.fake_get_fc_hbas_with_platform + fake_fc_hbas_info.side_effect \ + = self.fake_get_fc_hbas_info_with_platform + + name = 'volume-00000001' + vol = {'id': 1, 'name': name} + location = '10.0.2.15:3260' + wwn = '1234567890123456' + connection_info = self.fibrechan_connection(vol, location, wwn) + conn_data = self.connector._add_targets_to_connection_properties( + connection_info['data'] + ) + volume_paths = self.connector.get_volume_paths(conn_data) + + expected = ['/dev/disk/by-path' + '/platform-80040000000.peu0-c0-pci-0000:05:00.2' + '-fc-0x1234567890123456-lun-1'] + self.assertEqual(expected, volume_paths) + @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') diff --git a/os_brick/tests/initiator/connectors/test_fibre_channel_s390x.py b/os_brick/tests/initiator/connectors/test_fibre_channel_s390x.py index 9661bc857..98e38657d 100644 --- a/os_brick/tests/initiator/connectors/test_fibre_channel_s390x.py +++ b/os_brick/tests/initiator/connectors/test_fibre_channel_s390x.py @@ -59,7 +59,7 @@ class FibreChannelConnectorS390XTestCase(test_connector.ConnectorTestCase): self.assertEqual(lunstring, "0x4020400a00000000") @mock.patch.object(fibre_channel_s390x.FibreChannelConnectorS390X, - '_get_possible_devices', return_value=[(3, 5, 2), ]) + '_get_possible_devices', return_value=[('', 3, 5, 2), ]) @mock.patch.object(linuxfc.LinuxFibreChannelS390X, 'get_fc_hbas_info', return_value=[]) @mock.patch.object(linuxfc.LinuxFibreChannelS390X, diff --git a/releasenotes/notes/bug-1862443-e87ef38b60f9b979.yaml b/releasenotes/notes/bug-1862443-e87ef38b60f9b979.yaml new file mode 100644 index 000000000..99df9060b --- /dev/null +++ b/releasenotes/notes/bug-1862443-e87ef38b60f9b979.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + [`bug 1862433 `_] + Fix an issue where platform id is needed to determine name of scsi disk.