Lun id's > 255 should be converted to hex

This patch addresses the issue where lun id's values are larger
than 255 and are being kept as integers. This causes the volume and
search paths to be malformed and volumes can't be found. This patch
adds two functions to linuxscsi.py to process the lun id's; they can
process both a single lun id and a list of them. If a lun id has a
value larger than 255 it is converted to hex. This patch also modifies
the necessary unit tests and adds ones to cover the new main function.

Change-Id: Ib0b2f239a8152275de9ea66fa99a286dfbe53d57
Closes-bug: #1493350
This commit is contained in:
Jenkins 2016-02-11 17:22:19 +00:00 committed by Kendall Nelson
parent 71e5745fef
commit 82cdb40f87
4 changed files with 60 additions and 9 deletions

View File

@ -981,7 +981,8 @@ class ISCSIConnector(InitiatorConnector):
brackets. Udev code specifically forbids that.
"""
portal, iqn, lun = target
return (portal.replace('[', '').replace(']', ''), iqn, lun)
return (portal.replace('[', '').replace(']', ''), iqn,
self._linuxscsi.process_lun_id(lun))
def _get_device_path(self, connection_properties):
if self._get_transport() == "default":
@ -1453,7 +1454,7 @@ class FibreChannelConnector(InitiatorConnector):
host_device = "/dev/disk/by-path/pci-%s-fc-%s-lun-%s" % (
pci_num,
target_wwn,
lun)
self._linuxscsi.process_lun_id(lun))
host_devices.append(host_device)
return host_devices

View File

@ -409,3 +409,20 @@ class LinuxSCSI(executor.Executor):
return new_size
else:
return new_size
def process_lun_id(self, lun_ids):
if isinstance(lun_ids, list):
processed = []
for x in lun_ids:
x = self._format_lun_id(x)
processed.append(x)
else:
processed = self._format_lun_id(lun_ids)
return processed
def _format_lun_id(self, lun_id):
if lun_id < 256:
return lun_id
else:
return ("0x%04x%04x00000000" %
(lun_id & 0xffff, lun_id >> 16 & 0xffff))

View File

@ -622,10 +622,12 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
@mock.patch.object(connector.ISCSIConnector, '_get_multipath_device_name')
@mock.patch.object(connector.ISCSIConnector, '_get_multipath_iqns')
@mock.patch.object(connector.InitiatorConnector, '_discover_mpath_device')
@mock.patch.object(linuxscsi.LinuxSCSI, 'process_lun_id')
def test_connect_volume_with_multiple_portals(
self, mock_discover_mpath_device, mock_get_iqn, mock_device_name,
mock_run_multipath, mock_iscsi_devices,
mock_get_device_map, mock_devices, mock_exists, mock_scsi_wwn):
self, mock_process_lun_id, mock_discover_mpath_device,
mock_get_iqn, mock_device_name, mock_run_multipath,
mock_iscsi_devices, mock_get_device_map, mock_devices,
mock_exists, mock_scsi_wwn):
mock_scsi_wwn.return_value = FAKE_SCSI_WWN
location1 = '10.0.2.15:3260'
location2 = '[2001:db8::1]:3260'
@ -645,6 +647,7 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
mock_get_iqn.return_value = [iqn1, iqn2]
mock_discover_mpath_device.return_value = (fake_multipath_dev,
FAKE_SCSI_WWN)
mock_process_lun_id.return_value = [1, 2]
result = self.connector_with_multipath.connect_volume(
connection_properties['data'])
@ -678,11 +681,13 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
@mock.patch.object(connector.ISCSIConnector, '_get_multipath_iqns')
@mock.patch.object(connector.ISCSIConnector, '_run_iscsiadm')
@mock.patch.object(connector.InitiatorConnector, '_discover_mpath_device')
@mock.patch.object(linuxscsi.LinuxSCSI, 'process_lun_id')
def test_connect_volume_with_multiple_portals_primary_error(
self, mock_discover_mpath_device, mock_iscsiadm, mock_get_iqn,
mock_device_name, mock_run_multipath, mock_rescan_multipath,
mock_iscsi_devices, mock_get_multipath_device_map, mock_devices,
mock_exists, mock_scsi_wwn):
self, mock_process_lun_id, mock_discover_mpath_device,
mock_iscsiadm, mock_get_iqn, mock_device_name, mock_run_multipath,
mock_rescan_multipath, mock_iscsi_devices,
mock_get_multipath_device_map, mock_devices, mock_exists,
mock_scsi_wwn):
mock_scsi_wwn.return_value = FAKE_SCSI_WWN
location1 = '10.0.2.15:3260'
location2 = '[2001:db8::1]:3260'
@ -710,8 +715,10 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
mock_device_name.return_value = fake_multipath_dev
mock_get_iqn.return_value = [iqn2]
mock_iscsiadm.side_effect = fake_run_iscsiadm
mock_discover_mpath_device.return_value = (fake_multipath_dev,
FAKE_SCSI_WWN)
mock_process_lun_id.return_value = [1, 2]
props = connection_properties['data'].copy()
result = self.connector_with_multipath.connect_volume(

View File

@ -627,3 +627,29 @@ loop0 0"""
expected_cmds = ['tee -a /sys/bus/scsi/drivers/sd/0:0:0:1/rescan',
'multipathd reconfigure']
self.assertEqual(expected_cmds, self.cmds)
def test_process_lun_id_list(self):
lun_list = [2, 255, 88, 370, 5, 256]
result = self.linuxscsi.process_lun_id(lun_list)
expected = [2, 255, 88, '0x0172000000000000',
5, '0x0100000000000000']
self.assertEqual(expected, result)
def test_process_lun_id_single_val_make_hex(self):
lun_id = 499
result = self.linuxscsi.process_lun_id(lun_id)
expected = '0x01f3000000000000'
self.assertEqual(expected, result)
def test_process_lun_id_single_val_make_hex_border_case(self):
lun_id = 256
result = self.linuxscsi.process_lun_id(lun_id)
expected = '0x0100000000000000'
self.assertEqual(expected, result)
def test_process_lun_id_single_var_return(self):
lun_id = 13
result = self.linuxscsi.process_lun_id(lun_id)
expected = 13
self.assertEqual(expected, result)