Implement match-set type 3PAR FC VLUN creation
Creating match-set type FC VLUN, instead of host sees type. Passing node-slot-port details while creating a VLUN. This patch fixes dangling lun entry left when both ISCSI and FC attaches are made on the same compute host, after removing all attachments. Updated version number to 3.0.8. Updated broken unit test cases. Adding release note. Closes-Bug: #1577993 Change-Id: I927638584093130b0e94c9cdd8074b3617baa366
This commit is contained in:
parent
42db20e90a
commit
0912153358
@ -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,
|
||||
@ -4487,16 +4490,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 = {
|
||||
@ -4509,6 +4512,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" %
|
||||
@ -4517,6 +4527,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:
|
||||
@ -4534,11 +4554,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(
|
||||
@ -4546,7 +4575,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):
|
||||
@ -4587,7 +4616,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,
|
||||
@ -4655,16 +4684,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 = {
|
||||
@ -4677,6 +4706,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" %
|
||||
@ -4685,6 +4721,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:
|
||||
@ -4702,11 +4748,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(
|
||||
@ -4714,8 +4769,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):
|
||||
|
@ -101,10 +101,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)
|
||||
@ -265,26 +267,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
|
||||
|
||||
@ -296,7 +341,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)
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user