diff --git a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_common.py b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_common.py index 5cf1ed30cfa..5d14950b20f 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_common.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_common.py @@ -3893,6 +3893,26 @@ class PowerMaxCommonTest(test.TestCase): self.data.test_volume, None) self.assertEqual(self.data.rep_extra_specs_metro, extra_specs) + @mock.patch.object(utils.PowerMaxUtils, 'get_rdf_management_group_name') + def test_retype_volume_promotion_get_extra_specs_mgmt_group(self, mck_get): + array = self.data.array + srp = self.data.srp + device_id = self.data.device_id + volume = self.data.test_volume + volume_name = self.data.volume_id + extra_specs = deepcopy(self.data.rep_extra_specs) + target_slo = self.data.slo_silver + target_workload = self.data.workload + target_extra_specs = deepcopy(self.data.extra_specs) + target_extra_specs[utils.DISABLECOMPRESSION] = False + extra_specs[utils.REP_CONFIG] = self.data.rep_config_async + self.common.promotion = True + self.common._retype_volume( + array, srp, device_id, volume, volume_name, extra_specs, + target_slo, target_workload, target_extra_specs) + self.common.promotion = False + mck_get.assert_called_once_with(extra_specs[utils.REP_CONFIG]) + @mock.patch.object(rest.PowerMaxRest, 'is_volume_in_storagegroup', return_value=True) @mock.patch.object(masking.PowerMaxMasking, diff --git a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_replication.py b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_replication.py index 393360a7372..1554d2caeb1 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_replication.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/powermax/test_powermax_replication.py @@ -1207,6 +1207,10 @@ class PowerMaxReplicationTest(test.TestCase): self.assertTrue(success) self.common.promotion = False + @mock.patch.object( + common.PowerMaxCommon, 'update_metadata', + return_value={'metadata': { + 'Configuration': 'RDF2+TDEV', 'ReplicationEnabled': 'True'}}) @mock.patch.object( common.PowerMaxCommon, '_rdf_vols_partitioned', return_value=True) @@ -1221,7 +1225,8 @@ class PowerMaxReplicationTest(test.TestCase): common.PowerMaxCommon, '_retype_volume', return_value=(True, tpd.PowerMaxData.defaultstoragegroup_name)) def test_migrate_volume_success_rep_partitioned( - self, mck_retype, mck_get, mck_break, mck_valid, mck_partitioned): + self, mck_retype, mck_get, mck_break, mck_valid, mck_partitioned, + mck_update): array_id = self.data.array volume = self.data.test_rep_volume device_id = self.data.device_id @@ -1247,6 +1252,10 @@ class PowerMaxReplicationTest(test.TestCase): target_slo, target_workload, target_extra_specs) self.assertTrue(success) self.common.promotion = False + config_metadata = model_update['metadata']['Configuration'] + rep_metadata = model_update['metadata']['ReplicationEnabled'] + self.assertEqual('TDEV', config_metadata) + self.assertEqual('False', rep_metadata) @mock.patch.object(masking.PowerMaxMasking, 'add_volume_to_storage_group') @mock.patch.object(provision.PowerMaxProvision, 'get_or_create_group') diff --git a/cinder/volume/drivers/dell_emc/powermax/common.py b/cinder/volume/drivers/dell_emc/powermax/common.py index 352fb08bc74..6a3d34f18dc 100644 --- a/cinder/volume/drivers/dell_emc/powermax/common.py +++ b/cinder/volume/drivers/dell_emc/powermax/common.py @@ -3941,6 +3941,7 @@ class PowerMaxCommon(object): resume_target_sg, resume_original_sg = False, False resume_original_sg_dict = dict() orig_mgmt_sg_name = '' + is_partitioned = False target_extra_specs = new_type['extra_specs'] target_extra_specs.update({ @@ -4090,6 +4091,12 @@ class PowerMaxCommon(object): host_details[array_index] = array updated_host = '+'.join(host_details) model_update['host'] = updated_host + if is_partitioned: + # Must set these here as offline R1 promotion does + # not perform rdf cleanup. + model_update[ + 'metadata']['ReplicationEnabled'] = 'False' + model_update['metadata']['Configuration'] = 'TDEV' target_backend_id = None if is_rep_enabled: @@ -4221,7 +4228,12 @@ class PowerMaxCommon(object): parent_sg = None if self.utils.is_replication_enabled(target_extra_specs): is_re, rep_mode = True, target_extra_specs['rep_mode'] - if self.utils.is_replication_enabled(extra_specs): + mgmt_sg_name = self.utils.get_rdf_management_group_name( + target_extra_specs[utils.REP_CONFIG]) + if self.promotion and self.utils.is_replication_enabled(extra_specs): + # Need to check this when performing promotion while R1 is offline + # as RDF cleanup is not performed. Target is not RDF enabled + # in that scenario. mgmt_sg_name = self.utils.get_rdf_management_group_name( extra_specs[utils.REP_CONFIG]) diff --git a/releasenotes/notes/promotion_offline_r1_fix-f7a008d0d13a3eff.yaml b/releasenotes/notes/promotion_offline_r1_fix-f7a008d0d13a3eff.yaml new file mode 100644 index 00000000000..854a5bf946a --- /dev/null +++ b/releasenotes/notes/promotion_offline_r1_fix-f7a008d0d13a3eff.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + PowerMax Driver - `bug #1908920 + `_: This offline r1 + promotion fix resets replication enabled and configuration metadata + during promotion retype with offline r1 array. It also gets management + storage group name from source extra_specs during promotion.