Merge "Dell EMC SC: ISCSI initialize_connection fixes."

This commit is contained in:
Zuul 2018-03-20 15:45:11 +00:00 committed by Gerrit Code Review
commit 63aa5a9a7f
4 changed files with 93 additions and 19 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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.