Merge "NetApp fix for controller preferred path"

This commit is contained in:
Jenkins 2014-09-27 22:24:46 +00:00 committed by Gerrit Code Review
commit 332ea116bb
2 changed files with 75 additions and 11 deletions

View File

@ -118,6 +118,32 @@ class FakeEseriesServerHandler(object):
"currentControllerId": "070000000000000000000001",
"protectionInformationCapable": false, "mapped": false,
"reconPriority": 1, "protectionType":
"type1Protection"},
{"extremeProtection": false, "pitBaseVolume": true,
"dssMaxSegmentSize": 131072,
"totalSizeInBytes": "1073741824", "raidLevel": "raid6",
"volumeRef": "0200000060080E500023BB34000003FB515C2293",
"listOfMappings": [], "sectorOffset": "15",
"id": "0200000060080E500023BB34000003FB515C2293",
"wwn": "60080E500023BB3400001FC352D14CB2",
"capacity": "2147483648", "mgmtClientAttribute": 0,
"label": "CFDXJ67BLJH25DXCZFZD4NSF54",
"volumeFull": false,
"blkSize": 512, "volumeCopyTarget": false,
"volumeGroupRef":
"0400000060080E500023BB3400001F9F52CECC3F",
"preferredControllerId": "070000000000000000000001",
"currentManager": "070000000000000000000001",
"applicationTagOwned": false, "status": "optimal",
"segmentSize": 131072, "volumeUse": "standardVolume",
"action": "none", "preferredManager":
"070000000000000000000001", "volumeHandle": 15,
"offline": false, "preReadRedundancyCheckEnabled": false,
"dssPreallocEnabled": false, "name": "bdm-vc-test-1",
"worldWideName": "60080E500023BB3400001FC352D14CB2",
"currentControllerId": "070000000000000000000001",
"protectionInformationCapable": false, "mapped": false,
"reconPriority": 1, "protectionType":
"type1Protection"}]"""
elif re.match("^/storage-systems/[0-9a-zA-Z]+/volumes/[0-9A-Za-z]+$",
path):
@ -680,7 +706,7 @@ class NetAppEseriesIscsiDriverTestCase(test.TestCase):
maps = [{'lunMappingRef': 'hdkjsdhjsdh',
'mapRef': '8400000060080E500023C73400300381515BFBA3',
'volumeRef': 'CFDXJ67BLJH25DXCZFZD4NSF54',
'volumeRef': '0200000060080E500023BB34000003FB515C2293',
'lun': 2}]
self.driver._get_host_mapping_for_vol_frm_array = mock.Mock(
return_value=maps)
@ -834,3 +860,21 @@ class NetAppEseriesIscsiDriverTestCase(test.TestCase):
self.driver._create_volume,
self.fake_eseries_pool_label,
self.fake_eseries_volume_label, self.fake_size_gb)
def test_portal_for_vol_controller(self):
volume = {'id': 'vol_id', 'currentManager': 'ctrl1'}
vol_nomatch = {'id': 'vol_id', 'currentManager': 'ctrl3'}
portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
{'controller': 'ctrl1', 'iqn': 'iqn1'}]
portal = self.driver._get_iscsi_portal_for_vol(volume, portals)
self.assertEqual(portal, {'controller': 'ctrl1', 'iqn': 'iqn1'})
portal = self.driver._get_iscsi_portal_for_vol(vol_nomatch, portals)
self.assertEqual(portal, {'controller': 'ctrl2', 'iqn': 'iqn2'})
def test_portal_for_vol_any_false(self):
vol_nomatch = {'id': 'vol_id', 'currentManager': 'ctrl3'}
portals = [{'controller': 'ctrl2', 'iqn': 'iqn2'},
{'controller': 'ctrl1', 'iqn': 'iqn1'}]
self.assertRaises(exception.NetAppDriverException,
self.driver._get_iscsi_portal_for_vol,
vol_nomatch, portals, False)

View File

@ -254,11 +254,15 @@ class Driver(driver.ISCSIDriver):
try:
return self._get_cached_volume(label)
except KeyError:
for vol in self._client.list_volumes():
if vol.get('label') == label:
self._cache_volume(vol)
break
return self._get_cached_volume(label)
return self._get_latest_volume(uid)
def _get_latest_volume(self, uid):
label = utils.convert_uuid_to_es_fmt(uid)
for vol in self._client.list_volumes():
if vol.get('label') == label:
self._cache_volume(vol)
return self._get_cached_volume(label)
raise exception.NetAppDriverException(_("Volume %s not found."), uid)
def _get_cached_volume(self, label):
vol_id = self._objects['volumes']['label_ref'][label]
@ -504,8 +508,9 @@ class Driver(driver.ISCSIDriver):
def initialize_connection(self, volume, connector):
"""Allow connection to connector and return connection info."""
initiator_name = connector['initiator']
vol = self._get_volume(volume['id'])
iscsi_det = self._get_iscsi_service_details()
vol = self._get_latest_volume(volume['id'])
iscsi_details = self._get_iscsi_service_details()
iscsi_det = self._get_iscsi_portal_for_vol(vol, iscsi_details)
mapping = self._map_volume_to_host(vol, initiator_name)
lun_id = mapping['lun']
self._cache_vol_mapping(mapping)
@ -535,6 +540,7 @@ class Driver(driver.ISCSIDriver):
def _get_iscsi_service_details(self):
"""Gets iscsi iqn, ip and port information."""
ports = []
hw_inventory = self._client.list_hardware_inventory()
iscsi_ports = hw_inventory.get('iscsiPorts')
if iscsi_ports:
@ -550,9 +556,23 @@ class Driver(driver.ISCSIDriver):
iscsi_det['ip'] =\
port['ipv4Data']['ipv4AddressData']['ipv4Address']
iscsi_det['iqn'] = port['iqn']
iscsi_det['tcp_port'] = port.get('tcpListenPort', '3260')
return iscsi_det
msg = _('No good iscsi portal information found for %s.')
iscsi_det['tcp_port'] = port.get('tcpListenPort')
iscsi_det['controller'] = port.get('controllerId')
ports.append(iscsi_det)
if not ports:
msg = _('No good iscsi portals found for %s.')
raise exception.NetAppDriverException(
msg % self._client.get_system_id())
return ports
def _get_iscsi_portal_for_vol(self, volume, portals, anyController=True):
"""Get the iscsi portal info relevant to volume."""
for portal in portals:
if portal.get('controller') == volume.get('currentManager'):
return portal
if anyController and portals:
return portals[0]
msg = _('No good iscsi portal found in supplied list for %s.')
raise exception.NetAppDriverException(
msg % self._client.get_system_id())