From: TaoBai Date: Tue, 30 Jun 2015 07:03:38 +0000 (-0700) Subject: Storwize Driver zone removing X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e634215a0aa20b8bb1819b3f18f1727517b5e0a7;p=openstack-build%2Fcinder-build.git Storwize Driver zone removing 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 --- diff --git a/cinder/tests/unit/test_storwize_svc.py b/cinder/tests/unit/test_storwize_svc.py index 7653dc549..529efacbf 100644 --- a/cinder/tests/unit/test_storwize_svc.py +++ b/cinder/tests/unit/test_storwize_svc.py @@ -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) diff --git a/cinder/volume/drivers/ibm/storwize_svc/__init__.py b/cinder/volume/drivers/ibm/storwize_svc/__init__.py index 741fe598a..d5458ab29 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/__init__.py +++ b/cinder/volume/drivers/ibm/storwize_svc/__init__.py @@ -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): diff --git a/cinder/volume/drivers/ibm/storwize_svc/helpers.py b/cinder/volume/drivers/ibm/storwize_svc/helpers.py index bc089e6ec..109790d0c 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/helpers.py +++ b/cinder/volume/drivers/ibm/storwize_svc/helpers.py @@ -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):