]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Properly remove host object from ISE
authorRichard Hedlind <richard.hedlind@x-io.com>
Fri, 20 Mar 2015 02:30:39 +0000 (20:30 -0600)
committerRichard Hedlind <richard.hedlind@x-io.com>
Tue, 24 Mar 2015 22:05:51 +0000 (16:05 -0600)
This removes host object from ISE when terminate_connection
detects no more allocations for that host.

Change-Id: I31cc27bc95efaab3dca0c9a4c833655c43b73abf
Closes-Bug: 1433450

cinder/tests/test_xio.py
cinder/volume/drivers/xio.py

index e296534ed2e4800b1d988a27408b8ef8a157f4ec..7ad0cd889c244d7985a68d2ccb42845bfece37f8 100644 (file)
@@ -864,7 +864,7 @@ class XIOISEDriverTestCase(object):
             protocol = 'fibre_channel'
         exp_result = {}
         exp_result = {'vendor_name': "X-IO",
-                      'driver_version': "1.1.1",
+                      'driver_version': "1.1.2",
                       'volume_backend_name': backend_name,
                       'reserved_percentage': 0,
                       'total_capacity_gb': 100,
@@ -1120,6 +1120,9 @@ class XIOISEDriverTestCase(object):
             mock_req.side_effect = iter([ISE_GET_QUERY_RESP,
                                          ISE_GET_HOSTS_HOST1_RESP,
                                          ISE_GET_ALLOC_WITH_EP_RESP,
+                                         ISE_DELETE_ALLOC_RESP,
+                                         ISE_GET_ALLOC_WITH_EP_RESP,
+                                         ISE_GET_HOSTS_HOST1_RESP,
                                          ISE_DELETE_ALLOC_RESP])
         elif self.configuration.ise_protocol == 'fibre_channel':
             mock_req.side_effect = iter([ISE_GET_QUERY_RESP,
@@ -1127,7 +1130,9 @@ class XIOISEDriverTestCase(object):
                                          ISE_GET_ALLOC_WITH_EP_RESP,
                                          ISE_DELETE_ALLOC_RESP,
                                          ISE_GET_ALLOC_WITH_EP_RESP,
-                                         ISE_GET_CONTROLLERS_RESP])
+                                         ISE_GET_CONTROLLERS_RESP,
+                                         ISE_GET_HOSTS_HOST1_RESP,
+                                         ISE_DELETE_ALLOC_RESP])
         self.driver.terminate_connection(VOLUME1, self.connector)
 
     def test_terminate_connection_positive_noalloc(self, mock_req):
@@ -1135,13 +1140,18 @@ class XIOISEDriverTestCase(object):
         if self.configuration.ise_protocol == 'iscsi':
             mock_req.side_effect = iter([ISE_GET_QUERY_RESP,
                                          ISE_GET_HOSTS_HOST1_RESP,
-                                         ISE_GET_ALLOC_WITH_NO_ALLOC_RESP])
+                                         ISE_GET_ALLOC_WITH_NO_ALLOC_RESP,
+                                         ISE_GET_ALLOC_WITH_NO_ALLOC_RESP,
+                                         ISE_GET_HOSTS_HOST1_RESP,
+                                         ISE_DELETE_ALLOC_RESP])
         elif self.configuration.ise_protocol == 'fibre_channel':
             mock_req.side_effect = iter([ISE_GET_QUERY_RESP,
                                          ISE_GET_HOSTS_HOST1_RESP,
                                          ISE_GET_ALLOC_WITH_NO_ALLOC_RESP,
                                          ISE_GET_ALLOC_WITH_NO_ALLOC_RESP,
-                                         ISE_GET_CONTROLLERS_RESP])
+                                         ISE_GET_CONTROLLERS_RESP,
+                                         ISE_GET_HOSTS_HOST1_RESP,
+                                         ISE_DELETE_ALLOC_RESP])
         self.driver.terminate_connection(VOLUME1, self.connector)
 
     def test_negative_terminate_connection_bad_host(self, mock_req):
index 890ce12ddcc99a5f49d8a3505edc4d49a76fdf8a..c44f0ba4865df214913365d6cd517e4d20dc33a0 100644 (file)
@@ -64,12 +64,13 @@ def RaiseXIODriverException():
 
 class XIOISEDriver(object):
 
-    VERSION = '1.1.1'
+    VERSION = '1.1.2'
 
     # Version   Changes
     # 1.0.0     Base driver
     # 1.1.0     QoS, affinity, retype and thin support
     # 1.1.1     Fix retry loop (Bug 1429283)
+    # 1.1.2     Fix host object deletion (Bug 1433450).
 
     def __init__(self, *args, **kwargs):
         super(XIOISEDriver, self).__init__()
@@ -1398,6 +1399,14 @@ class XIOISEDriver(object):
     def local_path(self, volume):
         LOG.debug("X-IO local_path called.")
 
+    def delete_host(self, endpoints):
+        """Delete ISE host object"""
+        host = self._find_host(endpoints)
+        if host['locator'] != '':
+            # Delete host
+            self._send_cmd('DELETE', host['locator'], {})
+            LOG.debug("X-IO: host %s deleted", host['name'])
+
 
 # Protocol specific classes for entry.  They are wrappers around base class
 # above and every external API resuslts in a call to common function in base
@@ -1506,7 +1515,13 @@ class XIOISEISCSIDriver(driver.ISCSIDriver):
                 'data': data}
 
     def terminate_connection(self, volume, connector, **kwargs):
-        return self.driver.ise_unpresent(volume, connector['initiator'])
+        hostname = self.driver.ise_unpresent(volume, connector['initiator'])
+        alloc_cnt = 0
+        if hostname != '':
+            alloc_cnt = self.driver.find_allocations(hostname)
+            if alloc_cnt == 0:
+                # delete host object
+                self.driver.delete_host(connector['initiator'])
 
     def create_snapshot(self, snapshot):
         return self.driver.create_snapshot(snapshot)
@@ -1603,14 +1618,17 @@ class XIOISEFCDriver(driver.FibreChannelDriver):
         alloc_cnt = 0
         if hostname != '':
             alloc_cnt = self.driver.find_allocations(hostname)
-        if alloc_cnt == 0:
-            target_wwns = self.driver.find_target_wwns()
-            data['target_wwn'] = target_wwns
-            # build target initiator map
-            target_map = {}
-            for initiator in connector['wwpns']:
-                target_map[initiator] = target_wwns
-            data['initiator_target_map'] = target_map
+            if alloc_cnt == 0:
+                target_wwns = self.driver.find_target_wwns()
+                data['target_wwn'] = target_wwns
+                # build target initiator map
+                target_map = {}
+                for initiator in connector['wwpns']:
+                    target_map[initiator] = target_wwns
+                data['initiator_target_map'] = target_map
+                # delete host object
+                self.driver.delete_host(connector['wwpns'])
+
         return {'driver_volume_type': 'fibre_channel',
                 'data': data}