Merge "Implement match-set type 3PAR FC VLUN creation"

This commit is contained in:
Jenkins 2016-07-02 19:06:00 +00:00 committed by Gerrit Code Review
commit a63059db85
3 changed files with 129 additions and 27 deletions

View File

@ -121,11 +121,13 @@ class HPE3PARBaseDriver(object):
VOLUME_ID_SNAP = '761fc5e5-5191-4ec7-aeba-33e36de44156'
FAKE_DESC = 'test description name'
FAKE_FC_PORTS = [{'portPos': {'node': 7, 'slot': 1, 'cardPort': 1},
'type': 1,
'portWWN': '0987654321234',
'protocol': 1,
'mode': 2,
'linkState': 4},
{'portPos': {'node': 6, 'slot': 1, 'cardPort': 1},
'type': 1,
'portWWN': '123456789000987',
'protocol': 1,
'mode': 2,
@ -334,6 +336,7 @@ class HPE3PARBaseDriver(object):
'PORT_STATE_READY': 4,
'PORT_PROTO_ISCSI': 2,
'PORT_PROTO_FC': 1,
'PORT_TYPE_HOST': 1,
'TASK_DONE': TASK_DONE,
'TASK_ACTIVE': TASK_ACTIVE,
'HOST_EDIT_ADD': 1,
@ -4534,16 +4537,16 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
'firmwareVersion': None,
'hostSpeed': 0,
'model': None,
'portPos': {'cardPort': 1, 'node': 1,
'slot': 2},
'portPos': {'cardPort': 1, 'node': 7,
'slot': 1},
'vendor': None,
'wwn': self.wwn[0]},
{'driverVersion': None,
'firmwareVersion': None,
'hostSpeed': 0,
'model': None,
'portPos': {'cardPort': 1, 'node': 0,
'slot': 2},
'portPos': {'cardPort': 1, 'node': 6,
'slot': 1},
'vendor': None,
'wwn': self.wwn[1]}]}]
mock_client.queryHost.return_value = {
@ -4556,6 +4559,13 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
hpeexceptions.HTTPNotFound('fake'),
[{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'portPos': {'node': 7, 'slot': 1, 'cardPort': 1},
'remoteName': self.wwn[1],
'lun': 90, 'type': 0}],
[{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'portPos': {'node': 6, 'slot': 1, 'cardPort': 1},
'remoteName': self.wwn[0],
'lun': 90, 'type': 0}]]
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
@ -4564,6 +4574,16 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
'host': self.FAKE_HOST,
'nsp': 'something'})
mock_client.createVLUN.return_value = location
expected_properties = {
'driver_volume_type': 'fibre_channel',
'data': {
'encrypted': False,
'target_lun': 90,
'target_wwn': ['0987654321234', '123456789000987'],
'target_discovered': True,
'initiator_target_map':
{'123456789012345': ['123456789000987'],
'123456789054321': ['0987654321234']}}}
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
@ -4581,11 +4601,20 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
mock.call.getHost(self.FAKE_HOST),
mock.call.getPorts(),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.getPorts(),
mock.call.createVLUN(
self.VOLUME_3PAR_NAME,
auto=True,
hostname=self.FAKE_HOST,
lun=None),
lun=None,
portPos={'node': 7, 'slot': 1, 'cardPort': 1}),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.createVLUN(
self.VOLUME_3PAR_NAME,
auto=False,
hostname=self.FAKE_HOST,
lun=90,
portPos={'node': 6, 'slot': 1, 'cardPort': 1}),
mock.call.getHostVLUNs(self.FAKE_HOST)]
mock_client.assert_has_calls(
@ -4593,7 +4622,7 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
expected +
self.standard_logout)
self.assertDictMatch(self.properties, result)
self.assertDictMatch(expected_properties, result)
@mock.patch('cinder.zonemanager.utils.create_lookup_service')
def test_initialize_connection_with_lookup_single_nsp(self, mock_lookup):
@ -4634,7 +4663,7 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
[{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': 90, 'type': 0,
'portPos': {'cardPort': 1, 'node': 7, 'slot': 1}, }]]
'portPos': {'cardPort': 1, 'node': 7, 'slot': 1}}]]
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
{'volume_name': self.VOLUME_3PAR_NAME,
@ -4702,16 +4731,16 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
'firmwareVersion': None,
'hostSpeed': 0,
'model': None,
'portPos': {'cardPort': 1, 'node': 1,
'slot': 2},
'portPos': {'cardPort': 1, 'node': 7,
'slot': 1},
'vendor': None,
'wwn': self.wwn[0]},
{'driverVersion': None,
'firmwareVersion': None,
'hostSpeed': 0,
'model': None,
'portPos': {'cardPort': 1, 'node': 0,
'slot': 2},
'portPos': {'cardPort': 1, 'node': 6,
'slot': 1},
'vendor': None,
'wwn': self.wwn[1]}]}]
mock_client.queryHost.return_value = {
@ -4724,6 +4753,13 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
hpeexceptions.HTTPNotFound('fake'),
[{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': 90, 'type': 0,
'remoteName': self.wwn[1],
'portPos': {'cardPort': 1, 'node': 7, 'slot': 1}}],
[{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'portPos': {'node': 6, 'slot': 1, 'cardPort': 1},
'remoteName': self.wwn[0],
'lun': 90, 'type': 0}]]
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
@ -4732,6 +4768,16 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
'host': self.FAKE_HOST,
'nsp': 'something'})
mock_client.createVLUN.return_value = location
expected_properties = {
'driver_volume_type': 'fibre_channel',
'data': {
'encrypted': True,
'target_lun': 90,
'target_wwn': ['0987654321234', '123456789000987'],
'target_discovered': True,
'initiator_target_map':
{'123456789012345': ['123456789000987'],
'123456789054321': ['0987654321234']}}}
with mock.patch.object(hpecommon.HPE3PARCommon,
'_create_client') as mock_create_client:
@ -4749,11 +4795,20 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
mock.call.getHost(self.FAKE_HOST),
mock.call.getPorts(),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.getPorts(),
mock.call.createVLUN(
self.VOLUME_3PAR_NAME,
auto=True,
hostname=self.FAKE_HOST,
lun=None),
lun=None,
portPos={'node': 7, 'slot': 1, 'cardPort': 1}),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.createVLUN(
self.VOLUME_3PAR_NAME,
auto=False,
hostname=self.FAKE_HOST,
lun=90,
portPos={'node': 6, 'slot': 1, 'cardPort': 1}),
mock.call.getHostVLUNs(self.FAKE_HOST)]
mock_client.assert_has_calls(
@ -4761,8 +4816,6 @@ class TestHPE3PARFCDriver(HPE3PARBaseDriver, test.TestCase):
expected +
self.standard_logout)
expected_properties = self.properties
expected_properties['data']['encrypted'] = True
self.assertDictMatch(expected_properties, result)
def test_terminate_connection(self):

View File

@ -103,10 +103,12 @@ class HPE3PARFCDriver(driver.TransferVD,
3.0.5 - Optimize array ID retrieval
3.0.6 - Update replication to version 2.1
3.0.7 - Remove metadata that tracks the instance ID. bug #1572665
3.0.8 - NSP feature, creating FC Vlun as match set instead of
host sees. bug #1577993
"""
VERSION = "3.0.7"
VERSION = "3.0.8"
def __init__(self, *args, **kwargs):
super(HPE3PARFCDriver, self).__init__(*args, **kwargs)
@ -267,26 +269,69 @@ class HPE3PARFCDriver(driver.TransferVD,
try:
# we have to make sure we have a host
host = self._create_host(common, volume, connector)
target_wwns, init_targ_map, numPaths = \
self._build_initiator_target_map(common, connector)
# check if a VLUN already exists for this host
existing_vlun = common.find_existing_vlun(volume, host)
vlun = None
if existing_vlun is None:
# now that we have a host, create the VLUN
if self.lookup_service is not None and numPaths == 1:
nsp = None
active_fc_port_list = common.get_active_fc_target_ports()
for port in active_fc_port_list:
if port['portWWN'].lower() == target_wwns[0].lower():
nsp = port['nsp']
break
vlun = common.create_vlun(volume, host, nsp)
nsp = None
lun_id = None
active_fc_port_list = common.get_active_fc_target_ports()
if self.lookup_service:
if not init_targ_map:
msg = _("Setup is incomplete. Device mapping "
"not found from FC network. "
"Cannot perform VLUN creation.")
LOG.error(msg)
raise exception.FCSanLookupServiceException(msg)
for target_wwn in target_wwns:
for port in active_fc_port_list:
if port['portWWN'].lower() == target_wwn.lower():
nsp = port['nsp']
vlun = common.create_vlun(volume,
host,
nsp,
lun_id=lun_id)
if lun_id is None:
lun_id = vlun['lun']
break
else:
vlun = common.create_vlun(volume, host)
init_targ_map.clear()
del target_wwns[:]
host_connected_nsp = []
for fcpath in host['FCPaths']:
if 'portPos' in fcpath:
host_connected_nsp.append(
common.build_nsp(fcpath['portPos']))
for port in active_fc_port_list:
if (
port['type'] == common.client.PORT_TYPE_HOST and
port['nsp'] in host_connected_nsp
):
nsp = port['nsp']
vlun = common.create_vlun(volume,
host,
nsp,
lun_id=lun_id)
target_wwns.append(port['portWWN'])
if vlun['remoteName'] in init_targ_map:
init_targ_map[vlun['remoteName']].append(
port['portWWN'])
else:
init_targ_map[vlun['remoteName']] = [
port['portWWN']]
if lun_id is None:
lun_id = vlun['lun']
if lun_id is None:
# New vlun creation failed
msg = _('No new vlun(s) were created')
LOG.error(msg)
raise exception.VolumeDriverException(msg)
else:
vlun = existing_vlun
@ -298,7 +343,6 @@ class HPE3PARFCDriver(driver.TransferVD,
encryption_key_id = volume.get('encryption_key_id', None)
info['data']['encrypted'] = encryption_key_id is not None
return info
finally:
self._logout(common)

View File

@ -0,0 +1,5 @@
---
fixes:
- 3PAR driver creates FC VLUN of match-set type instead of host sees.
With match-set, the host will see the virtual volume on specified
NSP (Node-Slot-Port). This change in vlun type fixes bug 1577993.