Fixed 3PAR driver issue finding correct vlun

This patch fixes an issue that happens when
a volume is attached to the same host
more than once.  The driver wasn't looking
for the correct VLUN on the 3par after the
VLUN was created.  We now get the VLUN
information in the return of the creation call.

Change-Id: Id570094f29900c0adcffe6c9d4145c9ad5e3ce4e
Closes-Bug: #1313894
This commit is contained in:
Walter A. Boring IV 2014-04-28 14:30:47 -07:00
parent a221a30b32
commit 32bac00ea0
2 changed files with 41 additions and 10 deletions

View File

@ -995,6 +995,12 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
'lun': 90, 'type': 0}]
mock_client.getPorts.return_value = {
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
{'volume_name': self.VOLUME_3PAR_NAME,
'lun_id': 90,
'host': self.FAKE_HOST,
'nsp': 'something'})
mock_client.createVLUN.return_value = location
result = self.driver.initialize_connection(self.volume, self.connector)
@ -1317,6 +1323,12 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': self.TARGET_LUN, 'type': 0}]
location = ("%(volume_name)s,%(lun_id)s,%(host)s,%(nsp)s" %
{'volume_name': self.VOLUME_3PAR_NAME,
'lun_id': self.TARGET_LUN,
'host': self.FAKE_HOST,
'nsp': 'something'})
mock_client.createVLUN.return_value = location
result = self.driver.initialize_connection(self.volume, self.connector)

View File

@ -343,12 +343,26 @@ class HP3PARCommon(object):
def _create_3par_vlun(self, volume, hostname, nsp):
try:
location = None
if nsp is None:
self.client.createVLUN(volume, hostname=hostname, auto=True)
location = self.client.createVLUN(volume, hostname=hostname,
auto=True)
else:
port = self.build_portPos(nsp)
self.client.createVLUN(volume, hostname=hostname, auto=True,
portPos=port)
location = self.client.createVLUN(volume, hostname=hostname,
auto=True, portPos=port)
vlun_info = None
if location:
# The LUN id is returned as part of the location URI
vlun = location.split(',')
vlun_info = {'volume_name': vlun[0],
'lun_id': int(vlun[1]),
'host_name': vlun[2],
'nsp': vlun[3],
}
return vlun_info
except hpexceptions.HTTPBadRequest as e:
if 'must be in the same domain' in e.get_description():
@ -452,18 +466,23 @@ class HP3PARCommon(object):
'hp3par_cpg')})
self.stats = stats
def _get_vlun(self, volume_name, hostname):
def _get_vlun(self, volume_name, hostname, lun_id=None):
"""find a VLUN on a 3PAR host."""
vluns = self.client.getHostVLUNs(hostname)
found_vlun = None
for vlun in vluns:
if volume_name in vlun['volumeName']:
found_vlun = vlun
break
if lun_id:
if vlun['lun'] == lun_id:
found_vlun = vlun
break
else:
found_vlun = vlun
break
msg = (_("3PAR vlun %(name)s not found on host %(host)s") %
{'name': volume_name, 'host': hostname})
if found_vlun is None:
msg = (_("3PAR vlun %(name)s not found on host %(host)s") %
{'name': volume_name, 'host': hostname})
LOG.warn(msg)
return found_vlun
@ -473,8 +492,8 @@ class HP3PARCommon(object):
In order to export a volume on a 3PAR box, we have to create a VLUN.
"""
volume_name = self._get_3par_vol_name(volume['id'])
self._create_3par_vlun(volume_name, host['name'], nsp)
return self._get_vlun(volume_name, host['name'])
vlun_info = self._create_3par_vlun(volume_name, host['name'], nsp)
return self._get_vlun(volume_name, host['name'], vlun_info['lun_id'])
def delete_vlun(self, volume, hostname):
volume_name = self._get_3par_vol_name(volume['id'])