]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Storwize Driver zone removing
authorTaoBai <baitaosh@cn.ibm.com>
Tue, 30 Jun 2015 07:03:38 +0000 (00:03 -0700)
committerTaoBai <baitaosh@cn.ibm.com>
Tue, 7 Jul 2015 02:13:28 +0000 (02:13 +0000)
Storwize driver may remove zone even when the zone is still in use
by an attached volume. To fix this issue, we need only report initiator
and target map when there are no volumes attached.

Closes-Bug: 1468913

Change-Id: I075b8d37d4d312ae6d812b41bb3732f20987a72d

cinder/tests/unit/test_storwize_svc.py
cinder/volume/drivers/ibm/storwize_svc/__init__.py
cinder/volume/drivers/ibm/storwize_svc/helpers.py

index 7653dc54907140917f7bb600fe7cf8bdbb08bbfe..529efacbfc6ed3ecf787c081602e448c127dd2fb 100644 (file)
@@ -533,18 +533,13 @@ port_speed!N/A
         host_name = kwargs['host'].strip('\'\"') if 'host' in kwargs else None
         target_wwpn = kwargs['wwpn'] if 'wwpn' in kwargs else None
         host_infos = []
-
         for hv in self._hosts_list.values():
             if (not host_name) or (hv['host_name'] == host_name):
-                for mv in self._mappings_list.values():
-                    if mv['host'] == hv['host_name']:
-                        if not target_wwpn or target_wwpn in hv['wwpns']:
-                            host_infos.append(hv)
-                            break
-
+                if not target_wwpn or target_wwpn in hv['wwpns']:
+                    host_infos.append(hv)
+                    break
         if not len(host_infos):
             return ('', '')
-
         rows = []
         rows.append(['remote_wwpn', 'remote_nportid', 'id', 'node_name',
                      'local_wwpn', 'local_port', 'local_nportid', 'state',
@@ -554,7 +549,6 @@ port_speed!N/A
                 rows.append([wwpn, '123456', host_info['id'], 'nodeN',
                              'AABBCCDDEEFF0011', '1', '0123ABC', 'active',
                              host_info['host_name'], '', 'host'])
-
         if self._next_cmd_error['lsfabric'] == 'header_mismatch':
             rows[0].pop(0)
             self._next_cmd_error['lsfabric'] = ''
@@ -2387,11 +2381,20 @@ class StorwizeSVCDriverTestCase(test.TestCase):
                     self._set_flag('storwize_svc_npiv_compatibility_mode',
                                    False)
 
-            self.driver.terminate_connection(volume1, self._connector)
-            # for npiv compatibility test case, we need to terminate connection
+            ret = self.driver.terminate_connection(volume1, self._connector)
+            # For npiv compatibility test case, we need to terminate connection
             # to the 2nd volume
+            # Return the fc info only when last volume detached
             if protocol == 'FC' and self.USESIM:
-                self.driver.terminate_connection(volume2, self._connector)
+                # For the first volume detach, ret['data'] should be empty
+                # only ret['driver_volume_type'] returned
+                self.assertEqual({}, ret['data'])
+                self.assertEqual('fibre_channel', ret['driver_volume_type'])
+                ret = self.driver.terminate_connection(volume2,
+                                                       self._connector)
+                self.assertEqual('fibre_channel', ret['driver_volume_type'])
+                # wwpn is radom created
+                self.assertNotEqual({}, ret['data'])
             if self.USESIM:
                 ret = self.driver._helpers.get_host_from_connector(
                     self._connector)
index 741fe598a4067b5f39d63e7493e7cfde3980d809..d5458ab293dcebdc7e88578a344224cdc8ac4b04 100644 (file)
@@ -524,8 +524,8 @@ class StorwizeSVCDriver(san.SanDriver):
         """
         LOG.debug('enter: terminate_connection: volume %(vol)s with connector'
                   ' %(conn)s', {'vol': volume['id'], 'conn': connector})
-
         vol_name = volume['name']
+        info = {}
         if 'host' in connector:
             # maybe two hosts on the storage, one is for FC and the other for
             # iSCSI, so get host according to protocol
@@ -533,9 +533,13 @@ class StorwizeSVCDriver(san.SanDriver):
             connector = connector.copy()
             if vol_opts['protocol'] == 'FC':
                 connector.pop('initiator', None)
+                info = {'driver_volume_type': 'fibre_channel',
+                        'data': {}}
             elif vol_opts['protocol'] == 'iSCSI':
                 connector.pop('wwnns', None)
                 connector.pop('wwpns', None)
+                info = {'driver_volume_type': 'iscsi',
+                        'data': {}}
 
             host_name = self._helpers.get_host_from_connector(connector)
             if host_name is None:
@@ -547,20 +551,28 @@ class StorwizeSVCDriver(san.SanDriver):
             # See bug #1244257
             host_name = None
 
-        info = {}
-        if 'wwpns' in connector and host_name:
-            target_wwpns = self._helpers.get_conn_fc_wwpns(host_name)
-            init_targ_map = self._make_initiator_target_map(connector['wwpns'],
-                                                            target_wwpns)
-            info = {'driver_volume_type': 'fibre_channel',
-                    'data': {'initiator_target_map': init_targ_map}}
-
-        self._helpers.unmap_vol_from_host(vol_name, host_name)
+        # Unmap volumes, if hostname is None, need to get value from vdiskmap
+        host_name = self._helpers.unmap_vol_from_host(vol_name, host_name)
+
+        # Host_name could be none
+        if host_name:
+            resp = self._helpers.check_host_mapped_vols(host_name)
+            if not len(resp):
+                LOG.info(_LI("Need to remove FC Zone, building initiator "
+                             "target map."))
+                # Build info data structure for zone removing
+                if 'wwpns' in connector and host_name:
+                    target_wwpns = self._helpers.get_conn_fc_wwpns(host_name)
+                    init_targ_map = (self._make_initiator_target_map
+                                     (connector['wwpns'],
+                                      target_wwpns))
+                    info['data'] = {'initiator_target_map': init_targ_map}
+                # No volume mapped to the host, delete host from array
+                self._helpers.delete_host(host_name)
 
         LOG.debug('leave: terminate_connection: volume %(vol)s with '
                   'connector %(conn)s', {'vol': volume['id'],
                                          'conn': connector})
-
         return info
 
     def create_volume(self, volume):
index bc089e6ecd081b6dbb5b1c397ab987743c2a5442..109790d0c086031559f09e740db7251400562a99 100644 (file)
@@ -366,18 +366,16 @@ class StorwizeHelpers(object):
                 LOG.warning(_LW('unmap_vol_from_host: No mapping of volume '
                                 '%(vol_name)s to host %(host)s found.'),
                             {'vol_name': volume_name, 'host': host_name})
-
         # We now know that the mapping exists
         self.ssh.rmvdiskhostmap(host_name, volume_name)
 
-        # If this host has no more mappings, delete it
-        resp = self.ssh.lshostvdiskmap(host_name)
-        if not len(resp):
-            self.delete_host(host_name)
-
         LOG.debug('Leave: unmap_vol_from_host: volume %(volume_name)s from '
                   'host %(host_name)s.',
                   {'volume_name': volume_name, 'host_name': host_name})
+        return host_name
+
+    def check_host_mapped_vols(self, host_name):
+        return self.ssh.lshostvdiskmap(host_name)
 
     @staticmethod
     def build_default_opts(config):