Fetch and return SCSI WWN

This patch adds the SCSI WWN for iSCSI and FC based volumes
in the return for connect_volume calls.   This WWN can be used
to uniquely identify the volume.

Change-Id: Ic98cdd700bc9fa3467e8c7f3cdaa70c12414ad75
Implements: blueprint brick-scsi-wwn
This commit is contained in:
Walter A. Boring IV 2015-11-05 12:37:00 -08:00 committed by Walter A. Boring IV (hemna)
parent fb4b2e0475
commit 62450a866f
2 changed files with 31 additions and 8 deletions

View File

@ -544,7 +544,13 @@ class ISCSIConnector(InitiatorConnector):
"volume. Only using path %(device)s "
"for volume.", {'device': host_device})
# find out the WWN of the device
device_wwn = self._linuxscsi.get_scsi_wwn(host_device)
LOG.debug("Device WWN = '%(wwn)s'", {'wwn': device_wwn})
device_info['scsi_wwn'] = device_wwn
device_info['path'] = host_device
LOG.debug("connect_volume returning %s", device_info)
return device_info
@synchronized('connect_volume')
@ -1025,6 +1031,7 @@ class FibreChannelConnector(InitiatorConnector):
# find out the WWN of the device
device_wwn = self._linuxscsi.get_scsi_wwn(self.host_device)
LOG.debug("Device WWN = '%(wwn)s'", {'wwn': device_wwn})
device_info['scsi_wwn'] = device_wwn
# see if the new drive is part of a multipath
# device. If so, we'll use the multipath device.
@ -1065,6 +1072,7 @@ class FibreChannelConnector(InitiatorConnector):
device_path = self.host_device
device_info['path'] = device_path
LOG.debug("connect_volume returning %s", device_info)
return device_info
def _get_host_devices(self, possible_devs, lun):

View File

@ -41,6 +41,7 @@ from os_brick.tests import base
LOG = logging.getLogger(__name__)
MY_IP = '10.0.0.1'
FAKE_SCSI_WWN = '1234567890'
class ConnectorUtilsTestCase(base.TestCase):
@ -470,6 +471,7 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
mock_iscsiadm.assert_any_call(props, ('--logout',),
check_exit_code=[0, 21, 255])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
@mock.patch.object(connector.ISCSIConnector, '_run_iscsiadm_bare')
@mock.patch.object(connector.ISCSIConnector,
'_get_target_portals_from_iscsiadm_output')
@ -480,7 +482,9 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
@mock.patch.object(os.path, 'exists', return_value=True)
def test_connect_volume_with_multipath(
self, exists_mock, get_device_mock, rescan_multipath_mock,
rescan_iscsi_mock, connect_to_mock, portals_mock, iscsiadm_mock):
rescan_iscsi_mock, connect_to_mock, portals_mock, iscsiadm_mock,
mock_iscsi_wwn):
mock_iscsi_wwn.return_value = FAKE_SCSI_WWN
location = '10.0.2.15:3260'
name = 'volume-00000001'
iqn = 'iqn.2010-10.org.openstack:%s' % name
@ -496,7 +500,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
result = self.connector_with_multipath.connect_volume(
connection_properties['data'])
expected_result = {'path': 'iqn.2010-10.org.openstack:volume-00000001',
'type': 'block'}
'type': 'block',
'scsi_wwn': FAKE_SCSI_WWN}
self.assertEqual(result, expected_result)
@mock.patch.object(connector.ISCSIConnector,
@ -545,6 +550,7 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
self.connector_with_multipath.connect_volume,
connection_properties['data'])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
@mock.patch.object(os.path, 'exists', return_value=True)
@mock.patch.object(host_driver.HostDriver, 'get_all_block_devices')
@mock.patch.object(connector.ISCSIConnector, '_get_multipath_device_map',
@ -557,7 +563,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
def test_connect_volume_with_multiple_portals(
self, mock_get_iqn, mock_device_name, mock_run_multipath,
mock_rescan_multipath, mock_iscsi_devices,
mock_get_device_map, mock_devices, mock_exists):
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 = '10.0.3.15:3260'
name1 = 'volume-00000001-1'
@ -577,7 +584,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
result = self.connector_with_multipath.connect_volume(
connection_properties['data'])
expected_result = {'path': fake_multipath_dev, 'type': 'block'}
expected_result = {'path': fake_multipath_dev, 'type': 'block',
'scsi_wwn': FAKE_SCSI_WWN}
cmd_format = 'iscsiadm -m node -T %s -p %s --%s'
expected_commands = [cmd_format % (iqn1, location1, 'login'),
cmd_format % (iqn2, location2, 'login')]
@ -594,6 +602,7 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
for command in expected_commands:
self.assertIn(command, self.cmds)
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
@mock.patch.object(os.path, 'exists')
@mock.patch.object(host_driver.HostDriver, 'get_all_block_devices')
@mock.patch.object(connector.ISCSIConnector, '_get_multipath_device_map',
@ -607,7 +616,9 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
def test_connect_volume_with_multiple_portals_primary_error(
self, 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_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 = '10.0.3.15:3260'
name1 = 'volume-00000001-1'
@ -638,7 +649,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
result = self.connector_with_multipath.connect_volume(
connection_properties['data'])
expected_result = {'path': fake_multipath_dev, 'type': 'block'}
expected_result = {'path': fake_multipath_dev, 'type': 'block',
'scsi_wwn': FAKE_SCSI_WWN}
self.assertEqual(expected_result, result)
mock_device_name.assert_called_once_with(dev2)
props['target_portal'] = location1
@ -664,6 +676,7 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
mock_iscsiadm.assert_any_call(props, ('--logout',),
check_exit_code=[0, 21, 255])
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_scsi_wwn')
@mock.patch.object(os.path, 'exists', return_value=True)
@mock.patch.object(connector.ISCSIConnector,
'_get_target_portals_from_iscsiadm_output')
@ -676,7 +689,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
def test_connect_volume_with_multipath_connecting(
self, mock_device_name, mock_run_multipath,
mock_rescan_multipath, mock_iscsi_devices, mock_devices,
mock_connect, mock_portals, mock_exists):
mock_connect, mock_portals, mock_exists, mock_scsi_wwn):
mock_scsi_wwn.return_value = FAKE_SCSI_WWN
location1 = '10.0.2.15:3260'
location2 = '10.0.3.15:3260'
name1 = 'volume-00000001-1'
@ -696,7 +710,8 @@ class ISCSIConnectorTestCase(ConnectorTestCase):
result = self.connector_with_multipath.connect_volume(
connection_properties['data'])
expected_result = {'path': fake_multipath_dev, 'type': 'block'}
expected_result = {'path': fake_multipath_dev, 'type': 'block',
'scsi_wwn': FAKE_SCSI_WWN}
props1 = connection_properties['data'].copy()
props2 = connection_properties['data'].copy()
locations = list(set([location1, location2])) # order may change