Dell PowerFlex: Fixed volume detach issue

Problem:
Volumes attached prior to the os-brick < 6.13.0 and driver < 3.6.0
release does not store ``sdc_guid``. The detach workflow introduced
in os-brick=6.13.0 and driver=3.6.0 assumes ``sdc_guid`` is present,
causing detach operations to error for legacy attachments.

Fix:
Adds backward compatibility for detach operations on legacy volumes
that do not include an ``sdc_guid`` in the connector information. When
the ``sdc_guid`` field is missing, the detachment is now handled by
os-brick to ensure successful unmap operations for legacy attachments.

Depends-On: https://review.opendev.org/c/openstack/os-brick/+/974811
Closes-Bug: #2138280
Change-Id: Ie4272dcf4ff8baf9cee2abe897b317abf93698a9
Signed-off-by: Nilesh Thathagar <nilesh.thathagar@dell.com>
This commit is contained in:
Nilesh Thathagar
2026-01-13 11:20:29 +00:00
parent 00505d2587
commit 1fd0b7fc3b
4 changed files with 62 additions and 32 deletions

View File

@@ -170,11 +170,13 @@ class TestSDC(powerflex.TestPowerFlexDriver):
self.driver._detach_volume_from_host.assert_called_once_with(
self.volume, self.host_id)
def test__terminate_connection_no_connector(self):
self.assertRaises(exception.InvalidHost,
self.driver._terminate_connection,
self.volume,
{})
def test__terminate_connection_with_no_sdc_guid(self):
connector = {
"host": "fake-host"
}
self.driver._detach_volume_from_host = mock.MagicMock()
self.driver.terminate_connection(self.volume, connector)
self.driver._detach_volume_from_host.assert_not_called()
def test__terminate_connection_multiattached(self):
self.driver._is_multiattached_to_host = mock.MagicMock(

View File

@@ -92,9 +92,10 @@ class PowerFlexDriver(driver.VolumeDriver):
3.5.7 - Report trim/discard support.
3.5.8 - Added Cinder active/active support.
3.6.0 - Improved secret handling.
3.6.1 - Fix for Bug #2138280 volume detach issue.
"""
VERSION = "3.6.0"
VERSION = "3.6.1"
SUPPORTS_ACTIVE_ACTIVE = True
# ThirdPartySystems wiki
CI_WIKI_NAME = "DellEMC_PowerFlex_CI"
@@ -910,6 +911,11 @@ class PowerFlexDriver(driver.VolumeDriver):
volume_name = flex_utils.id_to_base64(vol_or_snap.id)
connection_properties["scaleIO_volname"] = volume_name
connection_properties["scaleIO_volume_id"] = vol_or_snap.provider_id
# This will be required when calling initialize connection on cinder
# side for operation like creating bootable volume from image.
# This indicates that handling for detach is done on the driver
# side and not on os-brick side.
connection_properties["sdc_guid"] = sdc_guid
# map volume
sdc_id = self._get_client().query_sdc_id_by_guid(sdc_guid)
@@ -1063,36 +1069,37 @@ class PowerFlexDriver(driver.VolumeDriver):
self._detach_volume_from_host(volume_or_snap)
return
try:
if "sdc_guid" in connector:
sdc_guid = connector["sdc_guid"]
except Exception:
msg = "Host IP is not configured."
raise exception.InvalidHost(reason=msg)
LOG.info("Terminate connection for %(vol_id)s to SDC %(sdc)s.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
if isinstance(volume_or_snap, Volume):
is_multiattached = self._is_multiattached_to_host(
volume_or_snap.volume_attachment,
connector["host"]
)
if is_multiattached:
# Do not detach volume if it is attached to more than one
# instance on the same host.
LOG.info("Will not terminate connection for "
"%(vol_id)s to initiator at %(sdc)s "
"because it's multiattach.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
return
LOG.info("Terminate connection for %(vol_id)s to SDC %(sdc)s.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
if isinstance(volume_or_snap, Volume):
is_multiattached = self._is_multiattached_to_host(
volume_or_snap.volume_attachment,
connector["host"]
)
if is_multiattached:
# Do not detach volume if it is attached to more than one
# instance on the same host.
LOG.info("Will not terminate connection for "
"%(vol_id)s to initiator at %(sdc)s "
"because it's multiattach.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
return
# unmap volume
host_id = self._get_client().query_sdc_id_by_guid(sdc_guid)
self._detach_volume_from_host(volume_or_snap, host_id)
# unmap volume
host_id = self._get_client().query_sdc_id_by_guid(sdc_guid)
self._detach_volume_from_host(volume_or_snap, host_id)
self._check_volume_unmapped(host_id, volume_or_snap.provider_id)
self._check_volume_unmapped(host_id, volume_or_snap.provider_id)
LOG.info("Terminated connection for %(vol_id)s to SDC %(sdc)s.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
LOG.info("Terminated connection for %(vol_id)s to SDC %(sdc)s.",
{"vol_id": volume_or_snap.id, "sdc": sdc_guid})
else:
LOG.info("Terminate legacy volume connection for "
"%(vol_id)s done at os-brick side.",
{"vol_id": volume_or_snap.id})
@staticmethod
def _is_multiattached_to_host(volume_attachment, host_name):

View File

@@ -228,7 +228,9 @@ Connector configuration
.. note::
Since 2025.2 release, users do not need to create connector configuration.
Since the 2025.2 release, connector configuration is no longer required
for new attachments. The connector.conf file must still be retained for
legacy attached volumes until they are fully detached.
Before using attach/detach volume operations PowerFlex connector must be
properly configured. On each node where PowerFlex SDC is installed do the

View File

@@ -0,0 +1,19 @@
---
upgrade:
- |
With the fix for `Bug #2138280
<https://bugs.launchpad.net/cinder/+bug/2138280>`_, starting from
os-brick version 6.15.0 or later, users must retain the
`/opt/emc/scaleio/openstack/connector.conf` file for volumes that were
attached using the legacy flow prior to the 6.13.0 release, until all
such legacy volumes are detached. For volumes attached using the new
attachment flow, the `/opt/emc/scaleio/openstack/connector.conf` file is
no longer required.
fixes:
- |
PowerFlex Driver `Bug #2138280
<https://bugs.launchpad.net/cinder/+bug/2138280>`_: Fixed an issue where
detach operations failed for volumes attached before the 6.13.0
release that did not include an `sdc_guid` in the connector information.
From os-brick version 6.15.0 or later, detach operations for these legacy
volumes are handled by os-brick to ensure backward compatibility.