]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fixed 3PAR driver issue finding correct vlun
authorWalter A. Boring IV <walter.boring@hp.com>
Mon, 28 Apr 2014 21:30:47 +0000 (14:30 -0700)
committerWalter A. Boring IV <walter.boring@hp.com>
Mon, 28 Apr 2014 21:33:44 +0000 (14:33 -0700)
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

cinder/tests/test_hp3par.py
cinder/volume/drivers/san/hp/hp_3par_common.py

index 119f6c4040bcea9261ca9a330e3f988f1db8fbd0..a5d77df86d3f4fd0c5125916af76619bfe63e7f6 100644 (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)
 
index 0b55b15658a1e353e503627e5b159c8b982e89a5..b1d188d503b6d2212d1778d890d3157de237e8f0 100644 (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'])