From 8a890c8369998676ba99658c0973c4409186de24 Mon Sep 17 00:00:00 2001 From: Helen Walsh Date: Mon, 21 Jun 2021 17:54:03 +0100 Subject: [PATCH] PowerMax Driver - Manage volume into correct storage group Manage a volume into the correct storage group if the name of the SRP on the remote differs to the SRP on the local array. For backward compatibility and name matching, the default storage group will assume the SRP name of the local array on both arrays. Closes-Bug: #1979666 Change-Id: Ie735b4a8607529ef3334242fd5a90c58f145adb4 --- .../dell_emc/powermax/test_powermax_common.py | 53 +++++++++++++++++++ .../drivers/dell_emc/powermax/common.py | 16 +++++- .../notes/diff-srps-674f2c0cc893db4b.yaml | 8 +++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/diff-srps-674f2c0cc893db4b.yaml 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 0bb68314f7f..5ed8461fc48 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 @@ -4782,3 +4782,56 @@ class PowerMaxCommonTest(test.TestCase): self.data.array, 'vol_name', self.data.device_id, self.data.extra_specs) mock_clean.assert_called_once() + + @mock.patch.object(rest.PowerMaxRest, 'srdf_create_device_pair', + return_value={ + 'tgt_device': tpd.PowerMaxData.device_id2}) + @mock.patch.object(rest.PowerMaxRest, 'get_rdf_group', + return_value=tpd.PowerMaxData.rdf_group_details) + @mock.patch.object( + common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=tpd.PowerMaxData.rep_extra_specs_rep_config) + @mock.patch.object(common.PowerMaxCommon, 'get_rdf_details', + return_value=(10, tpd.PowerMaxData.remote_array)) + def test_configure_volume_replication_srp_same( + self, mock_rdf, mock_res, mock_rdf_grp, mock_pair): + volume = fake_volume.fake_volume_obj( + context='cxt', provider_location=None) + with mock.patch.object( + self.masking, + 'get_or_create_default_storage_group') as mock_sg: + self.common.configure_volume_replication( + self.data.array, volume, self.data.device_id, + self.data.rep_extra_specs_rep_config) + mock_sg.assert_called_with( + self.data.remote_array, self.data.srp, 'Diamond', 'DSS', + self.data.rep_extra_specs_rep_config, False, is_re=True, + rep_mode='Synchronous') + + @mock.patch.object(rest.PowerMaxRest, 'srdf_create_device_pair', + return_value={ + 'tgt_device': tpd.PowerMaxData.device_id2}) + @mock.patch.object(rest.PowerMaxRest, 'get_rdf_group', + return_value=tpd.PowerMaxData.rdf_group_details) + @mock.patch.object( + common.PowerMaxCommon, '_get_replication_extra_specs', + return_value=tpd.PowerMaxData.rep_extra_specs_rep_config) + @mock.patch.object(common.PowerMaxCommon, 'get_rdf_details', + return_value=(10, tpd.PowerMaxData.remote_array)) + def test_configure_volume_replication_srp_diff( + self, mock_rdf, mock_res, mock_rdf_grp, mock_pair): + volume = fake_volume.fake_volume_obj( + context='cxt', provider_location=None) + + rep_extra_specs = deepcopy(self.data.rep_extra_specs_rep_config) + rep_extra_specs.update({'srp': 'REMOTE_SRP'}) + with mock.patch.object( + self.masking, + 'get_or_create_default_storage_group') as mock_sg: + self.common.configure_volume_replication( + self.data.array, volume, self.data.device_id, + self.data.rep_extra_specs_rep_config) + mock_sg.assert_called_with( + self.data.remote_array, self.data.srp, 'Diamond', 'DSS', + self.data.rep_extra_specs_rep_config, False, is_re=True, + rep_mode='Synchronous') diff --git a/cinder/volume/drivers/dell_emc/powermax/common.py b/cinder/volume/drivers/dell_emc/powermax/common.py index 5189a4845f5..67476c7848a 100644 --- a/cinder/volume/drivers/dell_emc/powermax/common.py +++ b/cinder/volume/drivers/dell_emc/powermax/common.py @@ -5039,8 +5039,16 @@ class PowerMaxCommon(object): device_uuid = self.utils.get_volume_element_name(volume.id) self.rest.rename_volume(remote_array, r2_device_id, device_uuid) + if rep_extra_specs['srp'].lower() != extra_specs['srp'].lower(): + LOG.warning("The source %(src)s and target %(tgt)s array SRPs " + "are different.", {'src': extra_specs['srp'], + 'tgt': rep_extra_specs['srp']}) + target_srp = extra_specs['srp'] + else: + target_srp = rep_extra_specs['srp'] + tgt_sg_name = self.masking.get_or_create_default_storage_group( - remote_array, rep_extra_specs['srp'], rep_extra_specs['slo'], + remote_array, target_srp, rep_extra_specs['slo'], rep_extra_specs['workload'], rep_extra_specs, disable_compression, is_re=True, rep_mode=rep_mode) remote_sg_get = True @@ -5707,6 +5715,12 @@ class PowerMaxCommon(object): rep_extra_specs = deepcopy(extra_specs) rep_extra_specs[utils.ARRAY] = rep_config['array'] rep_extra_specs[utils.SRP] = rep_config['srp'] + if extra_specs[utils.SRP].lower() != ( + rep_extra_specs[utils.SRP].lower()): + LOG.warning("The source %(src)s and target %(tgt)s array SRPs " + "are different.", {'src': extra_specs[utils.SRP], + 'tgt': rep_extra_specs[utils.SRP]}) + rep_extra_specs[utils.PORTGROUPNAME] = rep_config['portgroup'] # Get the RDF Group label & number diff --git a/releasenotes/notes/diff-srps-674f2c0cc893db4b.yaml b/releasenotes/notes/diff-srps-674f2c0cc893db4b.yaml new file mode 100644 index 00000000000..d84935c6add --- /dev/null +++ b/releasenotes/notes/diff-srps-674f2c0cc893db4b.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + `Bug #1979666 `_: + PowerMax driver : Fixed rare case where the SRP in the local and + remote arrays are different when managing volumes into OpenStack. + For backward compatibility and name matching, the default storage + group will assume the SRP name of the local array on both arrays.