From 521617e11783d4f39758b738da0ff9aa8bdc703d Mon Sep 17 00:00:00 2001 From: Helen Walsh Date: Tue, 1 Dec 2015 21:10:36 +0000 Subject: [PATCH] EMC VMAX - Method not being called for V3 The method _remove_last_vol_and_delete_sg to remove the last volume and delete the storage group was not being called for the VMAX3, due to an indentation error. Change-Id: I9a1fa59700233335fa50b02ff6cc3085a9e25b7a Closes-Bug: #1520549 --- cinder/tests/unit/test_emc_vmax.py | 36 +++++++++++++++ cinder/volume/drivers/emc/emc_vmax_fc.py | 2 + cinder/volume/drivers/emc/emc_vmax_iscsi.py | 2 + cinder/volume/drivers/emc/emc_vmax_masking.py | 44 ++++++++++++++++--- 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/cinder/tests/unit/test_emc_vmax.py b/cinder/tests/unit/test_emc_vmax.py index 259e6d84c..6c2bd5488 100644 --- a/cinder/tests/unit/test_emc_vmax.py +++ b/cinder/tests/unit/test_emc_vmax.py @@ -1998,6 +1998,42 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.common.utils._get_random_portgroup, dom) + def test_cleanup_last_vol(self): + conn = FakeEcomConnection() + masking = self.driver.common.masking + extraSpecs = {'volume_backend_name': 'GOLD_BE', + 'isV3': True} + controllerConfigService = ( + self.driver.utils.find_controller_configuration_service( + conn, self.data.storage_system)) + storageGroupName = self.data.storagegroupname + storageGroupInstanceName = ( + self.driver.utils.find_storage_masking_group( + conn, controllerConfigService, storageGroupName)) + volumeInstance = EMC_StorageVolume() + volumeInstance.path = ( + conn.EnumerateInstanceNames("EMC_StorageVolume")[0]) + + volumeName = self.data.test_volume['name'] + masking._last_volume_delete_masking_view = mock.Mock() + storageSystemInstanceName = ( + conn.EnumerateInstanceNames("EMC_StorageSystem")[0]) + # Failure case, an exception is thrown in + # _remove_last_vol_and_delete_sg so the returning the vol to + # the default SG cannot continue + self.assertRaises( + exception.VolumeBackendAPIException, + masking._cleanup_last_vol, conn, controllerConfigService, + storageGroupInstanceName, storageGroupName, volumeInstance, + volumeName, storageSystemInstanceName, False, extraSpecs) + + # Success case, the last vol is removed and the SG is deleted + masking._remove_last_vol_and_delete_sg = mock.Mock(return_value=True) + masking._cleanup_last_vol( + conn, controllerConfigService, storageGroupInstanceName, + storageGroupName, volumeInstance, volumeName, + storageSystemInstanceName, False, extraSpecs) + def test_generate_unique_trunc_pool(self): pool_under_16_chars = 'pool_under_16' pool1 = self.driver.utils.generate_unique_trunc_pool( diff --git a/cinder/volume/drivers/emc/emc_vmax_fc.py b/cinder/volume/drivers/emc/emc_vmax_fc.py index 484286439..66e6244d4 100644 --- a/cinder/volume/drivers/emc/emc_vmax_fc.py +++ b/cinder/volume/drivers/emc/emc_vmax_fc.py @@ -54,6 +54,8 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver): - Incorrect SG selected on an attach (#1515176) - Cleanup Zoning (bug #1501938) NOTE: FC only - Last volume in SG fix + - _remove_last_vol_and_delete_sg is not being called + for VMAX3 (bug #1520549) """ VERSION = "2.3.0" diff --git a/cinder/volume/drivers/emc/emc_vmax_iscsi.py b/cinder/volume/drivers/emc/emc_vmax_iscsi.py index 05eeb97f8..83c8b8553 100644 --- a/cinder/volume/drivers/emc/emc_vmax_iscsi.py +++ b/cinder/volume/drivers/emc/emc_vmax_iscsi.py @@ -60,6 +60,8 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver): - Incorrect SG selected on an attach (#1515176) - Cleanup Zoning (bug #1501938) NOTE: FC only - Last volume in SG fix + - _remove_last_vol_and_delete_sg is not being called + for VMAX3 (bug #1520549) """ VERSION = "2.3.0" diff --git a/cinder/volume/drivers/emc/emc_vmax_masking.py b/cinder/volume/drivers/emc/emc_vmax_masking.py index c3f794f03..d33c5462c 100644 --- a/cinder/volume/drivers/emc/emc_vmax_masking.py +++ b/cinder/volume/drivers/emc/emc_vmax_masking.py @@ -1964,14 +1964,39 @@ class EMCVMAXMasking(object): tierPolicyServiceInstanceName, storageSystemInstanceName['Name'], storageGroupInstanceName, extraSpecs) - # Remove the last volume and delete the storage group. - self._remove_last_vol_and_delete_sg( - conn, controllerConfigService, storageGroupInstanceName, - storageGroupName, volumeInstance.path, volumeName, - extraSpecs) + self._cleanup_last_vol( + conn, controllerConfigService, storageGroupInstanceName, + storageGroupName, volumeInstance, volumeName, + storageSystemInstanceName, isTieringPolicySupported, extraSpecs) + + def _cleanup_last_vol( + self, conn, controllerConfigService, storageGroupInstanceName, + storageGroupName, volumeInstance, volumeName, + storageSystemInstanceName, isTieringPolicySupported, extraSpecs): + """Do necessary cleanup when the volume is the last in the SG. + + This includes removing the last volume from the SG and deleting the + SG. It also means moving the volume to the default SG for VMAX3 and + FAST for VMAX2. + + :param conn: connection the the ecom server + :param controllerConfigService: the controller configuration service + :param storageGroupInstanceName: storage group instance name + :param storageGroupName: the storage group name + :param volumeInstance: the volume Instance + :param volumeName: the volume name + :param storageSystemInstanceName: the storage system instance name + :param isTieringPolicySupported: tiering policy supported flag + :param extraSpecs: extra specs + """ + # Remove the last volume and delete the storage group. + self._remove_last_vol_and_delete_sg( + conn, controllerConfigService, storageGroupInstanceName, + storageGroupName, volumeInstance.path, volumeName, + extraSpecs) # Add it back to the default storage group. - if isV3: + if extraSpecs[ISV3]: self._return_volume_to_default_storage_group_v3( conn, controllerConfigService, storageGroupName, volumeInstance, volumeName, storageSystemInstanceName, @@ -1979,10 +2004,17 @@ class EMCVMAXMasking(object): else: # V2 if FAST POLICY enabled, move the volume to the default # SG. + fastPolicyName = extraSpecs.get(FASTPOLICY, None) if fastPolicyName is not None and isTieringPolicySupported: self._cleanup_tiering( conn, controllerConfigService, fastPolicyName, volumeInstance, volumeName, extraSpecs) + LOG.debug( + "Volume %(volumeName)s successfully removed from SG and " + "returned to default storage group where applicable. " + "Storage Group %(storageGroupName)s successfully deleted. ", + {'volumeName': volumeName, + 'storageGroupName': storageGroupName}) def _get_sg_associated_with_connector( self, conn, controllerConfigService, volumeInstanceName, -- 2.45.2