]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fixing 3PAR connection name cache error
authorAnthony Lee <anthony.mic.lee@hp.com>
Tue, 9 Dec 2014 01:12:27 +0000 (17:12 -0800)
committerAnthony Lee <anthony.mic.lee@hp.com>
Thu, 18 Dec 2014 17:55:12 +0000 (09:55 -0800)
The 3PAR driver had a connection name cache in 3PAR common.  If
Cinder was restarted or the common object was destroyed the cache
was lost.  Instead of having the cache in 3PAR common, the 3PAR
driver can query the backend to see if there is a host already
available.  Replacing the name cache with a backend query had minimal
impact on performance of the driver and eliminates the problem of the
cache being destroyed/lost.

Closes-Bug: #1398914
Change-Id: Ie5467abc38946cceb4896fe9cbbd1606c7fbfba2

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

index 93719067fa27f2e92d60f66b64880ea2faeb8bfb..abdd6a44d01348f82a49dba03544f1814221bde4 100644 (file)
@@ -1801,6 +1801,12 @@ class HP3PARBaseDriver(object):
              'volumeName': self.VOLUME_3PAR_NAME,
              'lun': None, 'type': 0}]
 
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
+
         with mock.patch.object(hpcommon.HP3PARCommon, '_create_client')\
                 as mock_create_client:
             mock_create_client.return_value = mock_client
@@ -1810,6 +1816,7 @@ class HP3PARBaseDriver(object):
                 force=True)
 
             expected = [
+                mock.call.queryHost(iqns=[self.connector['initiator']]),
                 mock.call.getHostVLUNs(self.FAKE_HOST),
                 mock.call.deleteVLUN(
                     self.VOLUME_3PAR_NAME,
@@ -2789,7 +2796,14 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
 
         mock_client.getHostVLUNs.side_effect = effects
 
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
+
         expected = [
+            mock.call.queryHost(wwns=['123456789012345', '123456789054321']),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
@@ -2859,9 +2873,16 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
               'lun': None, 'type': 0}],
             hpexceptions.HTTPNotFound]
 
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
+
         mock_client.getHostVLUNs.side_effect = effects
 
         expected = [
+            mock.call.queryHost(wwns=['123456789012345', '123456789054321']),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
@@ -2923,7 +2944,14 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
                  'lun': None, 'type': 0},
             ]
 
+        mock_client.queryHost.return_value = {
+            'members': [{
+                'name': self.FAKE_HOST
+            }]
+        }
+
         expect_less = [
+            mock.call.queryHost(wwns=['123456789012345', '123456789054321']),
             mock.call.getHostVLUNs(self.FAKE_HOST),
             mock.call.deleteVLUN(
                 self.VOLUME_3PAR_NAME,
index 0a697799b38acf26ef64f6b803b3897dd7d7915d..9b60ad16c84b0e474ef08ca24e8c5545f62c459a 100644 (file)
@@ -160,10 +160,11 @@ class HP3PARCommon(object):
         2.0.28 - Removing locks bug #1381190
         2.0.29 - Report a limitless cpg's stats better bug #1398651
         2.0.30 - Update the minimum hp3parclient version bug #1402115
+        2.0.31 - Removed usage of host name cache #1398914
 
     """
 
-    VERSION = "2.0.30"
+    VERSION = "2.0.31"
 
     stats = {}
 
@@ -199,7 +200,6 @@ class HP3PARCommon(object):
 
     def __init__(self, config):
         self.config = config
-        self.hosts_naming_dict = dict()
         self.client = None
         self.uuid = uuid.uuid4()
 
@@ -767,7 +767,6 @@ class HP3PARCommon(object):
 
             try:
                 self._delete_3par_host(hostname)
-                self._remove_hosts_naming_dict_host(hostname)
             except Exception as ex:
                 # Any exception down here is only logged.  The vlun is deleted.
 
@@ -786,15 +785,6 @@ class HP3PARCommon(object):
                         'reason': ex.get_description()})
                 LOG.info(msg)
 
-    def _remove_hosts_naming_dict_host(self, hostname):
-        items = self.hosts_naming_dict.items()
-        lkey = None
-        for key, value in items:
-            if value == hostname:
-                lkey = key
-        if lkey is not None:
-            del self.hosts_naming_dict[lkey]
-
     def _get_volume_type(self, type_id):
         ctxt = context.get_admin_context()
         return volume_types.get_volume_type(ctxt, type_id)
@@ -1606,10 +1596,17 @@ class HP3PARCommon(object):
 
     def terminate_connection(self, volume, hostname, wwn=None, iqn=None):
         """Driver entry point to unattach a volume from an instance."""
+        # does 3par know this host by a different name?
+        hosts = None
+        if wwn:
+            hosts = self.client.queryHost(wwns=wwn)
+        elif iqn:
+            hosts = self.client.queryHost(iqns=[iqn])
+
+        if hosts and hosts['members'] and 'name' in hosts['members'][0]:
+            hostname = hosts['members'][0]['name']
+
         try:
-            # does 3par know this host by a different name?
-            if hostname in self.hosts_naming_dict:
-                hostname = self.hosts_naming_dict.get(hostname)
             self.delete_vlun(volume, hostname)
             return
         except hpexceptions.HTTPNotFound as e:
index dcf9453b8d0f25a497afabafddd523f4f3c75cd6..4bec1a7ecf8943de862c73d5b689cf08183f4d87 100644 (file)
@@ -74,10 +74,11 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         2.0.11 - Removing locks bug #1381190
         2.0.12 - Fix queryHost call to specify wwns bug #1398206
         2.0.13 - Fix missing host name during attach bug #1398206
+        2.0.14 - Removed usage of host name cache #1398914
 
     """
 
-    VERSION = "2.0.13"
+    VERSION = "2.0.14"
 
     def __init__(self, *args, **kwargs):
         super(HP3PARFCDriver, self).__init__(*args, **kwargs)
@@ -325,7 +326,6 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
             host_found = hosts['members'][0]['name']
 
         if host_found is not None:
-            common.hosts_naming_dict[hostname] = host_found
             return host_found
         else:
             persona_id = int(persona_id)
index 612160a39ae23db6dd3eecd7bcc833f07adcfd4d..7a433c95817b8389ba6f84119bcbc65455c14b1c 100644 (file)
@@ -78,10 +78,11 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         2.0.9 - Removing locks bug #1381190
         2.0.10 - Add call to queryHost instead SSH based findHost #1398206
         2.0.11 - Added missing host name during attach fix #1398206
+        2.0.12 - Removed usage of host name cache #1398914
 
     """
 
-    VERSION = "2.0.11"
+    VERSION = "2.0.12"
 
     def __init__(self, *args, **kwargs):
         super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
@@ -361,7 +362,6 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
             host_found = hosts['members'][0]['name']
 
         if host_found is not None:
-            common.hosts_naming_dict[hostname] = host_found
             return host_found
         else:
             if isinstance(iscsi_iqn, str) or isinstance(iscsi_iqn, unicode):