From: Walter A. Boring IV Date: Mon, 28 Apr 2014 21:30:47 +0000 (-0700) Subject: Fixed 3PAR driver issue finding correct vlun X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=32bac00ea003015add0d33be262cb3002e4c43af;p=openstack-build%2Fcinder-build.git 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 --- diff --git a/cinder/tests/test_hp3par.py b/cinder/tests/test_hp3par.py index 119f6c404..a5d77df86 100644 --- a/cinder/tests/test_hp3par.py +++ b/cinder/tests/test_hp3par.py @@ -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) diff --git a/cinder/volume/drivers/san/hp/hp_3par_common.py b/cinder/volume/drivers/san/hp/hp_3par_common.py index 0b55b1565..b1d188d50 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_common.py +++ b/cinder/volume/drivers/san/hp/hp_3par_common.py @@ -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'])