diff --git a/cinder/volume/drivers/ibm/ibm_storage/ds8k_helper.py b/cinder/volume/drivers/ibm/ibm_storage/ds8k_helper.py index 7a2c443ef05..5a7555e1368 100644 --- a/cinder/volume/drivers/ibm/ibm_storage/ds8k_helper.py +++ b/cinder/volume/drivers/ibm/ibm_storage/ds8k_helper.py @@ -678,7 +678,8 @@ class DS8KCommonHelper(object): } @coordination.synchronized('ibm-ds8k-{connector[host]}') - def terminate_connection(self, vol_id, host_id, connector, map_info): + def terminate_connection(self, volume, vol_id, host_id, connector, + map_info): host = self._get_host(connector) host_ports = map_info['host_ports'] lun_ids = map_info['lun_ids'] @@ -690,6 +691,27 @@ class DS8KCommonHelper(object): {"host": host_ports, "defined": host_id, "delete": delete_ports}) + host_name = host.name + if (host.name[:7] == "OShost:"): + host_name = host.name[7:] + attachment_count = 0 + if hasattr(volume, 'multiattach') and volume.multiattach: + try: + attachment_list = volume.volume_attachment + for attachment in attachment_list: + if (attachment.attach_status == "attached" and + attachment.attached_host == host_name): + attachment_count += 1 + except AttributeError: + pass + if attachment_count > 1: + LOG.info("Volume %(volume)s is attached to multiple " + "instances on host %(host)s, hence " + "skipping delete host.", + {'volume': volume.name, + 'host': host.name}) + return + for lun_id in lun_ids: self._delete_mappings(host_id, lun_id) if not lun_ids: @@ -1263,7 +1285,8 @@ class DS8KECKDHelper(DS8KCommonHelper): } } - def terminate_connection(self, vol_id, connector, force, **kwargs): + def terminate_connection(self, volume, vol_id, connector, force, + **kwargs): return None diff --git a/cinder/volume/drivers/ibm/ibm_storage/ds8k_proxy.py b/cinder/volume/drivers/ibm/ibm_storage/ds8k_proxy.py index fa207bd7b16..9f9b03991e3 100644 --- a/cinder/volume/drivers/ibm/ibm_storage/ds8k_proxy.py +++ b/cinder/volume/drivers/ibm/ibm_storage/ds8k_proxy.py @@ -1113,8 +1113,9 @@ class DS8KProxy(proxy.IBMStorageProxy): backend_helper = self._helper if isinstance(backend_helper, helper.DS8KECKDHelper): LOG.info('Detach the volume %s.', lun.ds_id) - return backend_helper.terminate_connection(lun.ds_id, connector, - force, **kwargs) + return backend_helper.terminate_connection(volume, lun.ds_id, + connector, force, + **kwargs) else: vol_mapped, host_id, map_info = ( backend_helper.check_vol_mapped_to_host(connector, lun.ds_id)) @@ -1155,11 +1156,13 @@ class DS8KProxy(proxy.IBMStorageProxy): else: LOG.info('Detach the volume %s.', lun.replica_ds_id) return backend_helper.terminate_connection( - lun.replica_ds_id, host_id, connector, map_info) + volume, lun.replica_ds_id, host_id, connector, + map_info) elif host_id and vol_mapped: LOG.info('Detaching volume %s.', lun.ds_id) - return backend_helper.terminate_connection(lun.ds_id, host_id, - connector, map_info) + return backend_helper.terminate_connection(volume, lun.ds_id, + host_id, connector, + map_info) @proxy.logger def create_group(self, ctxt, group): diff --git a/releasenotes/notes/bug-1951046-ds8k_fixed_detach_for_multi_attach_volumes-b86940efafa926f2.yaml b/releasenotes/notes/bug-1951046-ds8k_fixed_detach_for_multi_attach_volumes-b86940efafa926f2.yaml new file mode 100644 index 00000000000..4a7d5177aeb --- /dev/null +++ b/releasenotes/notes/bug-1951046-ds8k_fixed_detach_for_multi_attach_volumes-b86940efafa926f2.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + IBM DS8000 Driver `Bug #1951046 + `_: + Fixed detach issue for multi-attach volumes. Detach + the volume without deleting the host until attachment + count is zero.