Dell EMC SC: ISCSI initialize_connection fixes.
Driver was not honoring the server in ISCSI and returning connection information for all servers (IQNs) connected to a volume. If multiple servers are mapped to a volume the driver was only returning the first server for a given portal. Closes-Bug: #1756914 Change-Id: If65780000fa8f59f663b00b88584cf289effa590
This commit is contained in:
parent
08cfa44d35
commit
f8980ea128
@ -3641,7 +3641,50 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
self.assertTrue(mock_find_active_controller.called)
|
||||
expected = {'target_discovered': False,
|
||||
'target_iqn':
|
||||
u'iqn.2002-03.com.compellent:5000d31000fcbe43',
|
||||
'target_iqns':
|
||||
[u'iqn.2002-03.com.compellent:5000d31000fcbe43'],
|
||||
'target_lun': 1,
|
||||
'target_luns': [1],
|
||||
'target_portal': u'192.168.0.21:3260',
|
||||
'target_portals': [u'192.168.0.21:3260']}
|
||||
self.assertEqual(expected, res, 'Wrong Target Info')
|
||||
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
'_find_active_controller',
|
||||
return_value='64702.5764839588723736131.91')
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
'_find_controller_port',
|
||||
return_value=ISCSI_CTRLR_PORT)
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
'_find_domains',
|
||||
return_value=ISCSI_FLT_DOMAINS)
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
'_find_mappings',
|
||||
return_value=MAPPINGS)
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
'_is_virtualport_mode',
|
||||
return_value=True)
|
||||
def test_find_iscsi_properties_multiple_servers_mapped(
|
||||
self, mock_is_virtualport_mode, mock_find_mappings,
|
||||
mock_find_domains, mock_find_ctrl_port,
|
||||
mock_find_active_controller, mock_close_connection,
|
||||
mock_open_connection, mock_init):
|
||||
mappings = [{'instanceId': '64702.970.64702',
|
||||
'server': {'instanceId': '64702.47'},
|
||||
'volume': {'instanceId': '64702.92'}}]
|
||||
mappings.append(self.MAPPINGS[0].copy())
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
@ -3666,10 +3709,12 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where there are no ScMapping(s)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.scapi.find_iscsi_properties,
|
||||
self.VOLUME)
|
||||
self.VOLUME,
|
||||
scserver)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
|
||||
@mock.patch.object(storagecenter_api.SCApi,
|
||||
@ -3696,10 +3741,11 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where there are no ScFaultDomain(s)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.scapi.find_iscsi_properties,
|
||||
self.VOLUME)
|
||||
self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
@ -3726,10 +3772,11 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where there are no ScFaultDomain(s)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.scapi.find_iscsi_properties,
|
||||
self.VOLUME)
|
||||
self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -3759,8 +3806,9 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where Read Only mappings are found
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
@ -3804,7 +3852,8 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_find_ctrl_port.side_effect = [
|
||||
{'iscsiName': 'iqn.2002-03.com.compellent:5000d31000fcbe43'},
|
||||
{'iscsiName': 'iqn.2002-03.com.compellent:5000d31000fcbe44'}]
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -3854,7 +3903,8 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
# Test case where there are multiple portals and
|
||||
mock_find_ctrl_port.return_value = {
|
||||
'iscsiName': 'iqn.2002-03.com.compellent:5000d31000fcbe43'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_domains.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -3898,7 +3948,8 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -3940,9 +3991,10 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.scapi.find_iscsi_properties,
|
||||
self.VOLUME)
|
||||
self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -3973,8 +4025,9 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_close_connection,
|
||||
mock_open_connection,
|
||||
mock_init):
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where Read Only mappings are found
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_is_virtualport_mode.called)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
@ -4018,8 +4071,9 @@ class DellSCSanAPITestCase(test.TestCase):
|
||||
mock_find_ctrl_port.side_effect = [
|
||||
{'iscsiName': 'iqn.2002-03.com.compellent:5000d31000fcbe43'},
|
||||
{'iscsiName': 'iqn.2002-03.com.compellent:5000d31000fcbe44'}]
|
||||
scserver = {'instanceId': '64702.30'}
|
||||
# Test case where there are multiple portals
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME)
|
||||
res = self.scapi.find_iscsi_properties(self.VOLUME, scserver)
|
||||
self.assertTrue(mock_find_mappings.called)
|
||||
self.assertTrue(mock_find_ctrl_port.called)
|
||||
self.assertTrue(mock_find_active_controller.called)
|
||||
|
@ -1776,12 +1776,13 @@ class SCApi(object):
|
||||
'Error finding configuration: %s', cportid)
|
||||
return controllerport
|
||||
|
||||
def find_iscsi_properties(self, scvolume):
|
||||
def find_iscsi_properties(self, scvolume, scserver):
|
||||
"""Finds target information for a given Dell scvolume object mapping.
|
||||
|
||||
The data coming back is both the preferred path and all the paths.
|
||||
|
||||
:param scvolume: The dell sc volume object.
|
||||
:param scserver: The dell sc server object.
|
||||
:returns: iSCSI property dictionary.
|
||||
:raises VolumeBackendAPIException:
|
||||
"""
|
||||
@ -1813,9 +1814,12 @@ class SCApi(object):
|
||||
# Make sure this isn't a duplicate.
|
||||
newportal = address + ':' + six.text_type(port)
|
||||
for idx, portal in enumerate(portals):
|
||||
if portal == newportal and iqns[idx] == iqn:
|
||||
if (portal == newportal
|
||||
and iqns[idx] == iqn
|
||||
and luns[idx] == lun):
|
||||
LOG.debug('Skipping duplicate portal %(ptrl)s and'
|
||||
'iqn %(iqn)s.', {'ptrl': portal, 'iqn': iqn})
|
||||
' iqn %(iqn)s and lun %(lun)s.',
|
||||
{'ptrl': portal, 'iqn': iqn, 'lun': lun})
|
||||
return
|
||||
# It isn't in the list so process it.
|
||||
portals.append(newportal)
|
||||
@ -1849,10 +1853,17 @@ class SCApi(object):
|
||||
isvpmode = self._is_virtualport_mode(ssn)
|
||||
# Trundle through our mappings.
|
||||
for mapping in mappings:
|
||||
# Don't return remote sc links.
|
||||
msrv = mapping.get('server')
|
||||
if msrv and msrv.get('objectType') == 'ScRemoteStorageCenter':
|
||||
continue
|
||||
if msrv:
|
||||
# Don't return remote sc links.
|
||||
if msrv.get('objectType') == 'ScRemoteStorageCenter':
|
||||
continue
|
||||
# Don't return information for other servers. But
|
||||
# do log it.
|
||||
if self._get_id(msrv) != self._get_id(scserver):
|
||||
LOG.debug('find_iscsi_properties: Multiple servers'
|
||||
' attached to volume.')
|
||||
continue
|
||||
|
||||
# The lun, ro mode and status are in the mapping.
|
||||
LOG.debug('find_iscsi_properties: mapping: %s', mapping)
|
||||
|
@ -141,7 +141,8 @@ class SCISCSIDriver(storagecenter_common.SCCommonDriver,
|
||||
# 3. OS brick is calling us in single path mode so
|
||||
# we want to return Target_Portal and
|
||||
# Target_Portals as alternates.
|
||||
iscsiprops = api.find_iscsi_properties(scvolume)
|
||||
iscsiprops = api.find_iscsi_properties(scvolume,
|
||||
scserver)
|
||||
|
||||
# If this is a live volume we need to map up our
|
||||
# secondary volume. Note that if we have failed
|
||||
@ -204,7 +205,8 @@ class SCISCSIDriver(storagecenter_common.SCCommonDriver,
|
||||
secondaryvol = api.get_volume(
|
||||
sclivevolume['secondaryVolume']['instanceId'])
|
||||
if secondaryvol:
|
||||
return api.find_iscsi_properties(secondaryvol)
|
||||
return api.find_iscsi_properties(secondaryvol,
|
||||
secondary)
|
||||
# Dummy return on failure.
|
||||
data = {'target_discovered': False,
|
||||
'target_iqn': None,
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- Dell EMC SC driver correctly returns initialize_connection
|
||||
data when more than one IQN is attached to a volume. This
|
||||
fixes some random Nova Live Migration failures where the
|
||||
connection information being returned was for an IQN other
|
||||
than the one for which it was being requested.
|
Loading…
Reference in New Issue
Block a user