diff --git a/cinder/tests/unit/volume/drivers/dell_emc/powerflex/test_replication.py b/cinder/tests/unit/volume/drivers/dell_emc/powerflex/test_replication.py index 50649b1186f..42ba6b31d00 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/powerflex/test_replication.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/powerflex/test_replication.py @@ -110,3 +110,23 @@ class TestReplication(powerflex.TestPowerFlexDriver): context={}, volumes=[], secondary_id=secondary_id) + + def test_failover_aa(self): + self.test_do_setup_replication_configured() + self.driver.failover({}, [], self.replication_backend_id) + self.driver.failover_completed({}, "failed over") + self.assertEqual(self.replication_backend_id, + self.driver.active_backend_id) + + def test_failback_aa(self): + self.test_do_setup_already_failed_over() + self.driver.failover({}, [], 'default') + self.driver.failover_completed({}) + self.assertEqual('default', self.driver.active_backend_id) + + def test_failover_completed_invalid(self): + self.test_do_setup_replication_configured() + self.assertRaises(exception.InvalidReplicationTarget, + self.driver.failover_completed, + context={}, + active_backend_id="not_valid_target") diff --git a/cinder/volume/drivers/dell_emc/powerflex/driver.py b/cinder/volume/drivers/dell_emc/powerflex/driver.py index 2df2c4463b1..435b5386399 100644 --- a/cinder/volume/drivers/dell_emc/powerflex/driver.py +++ b/cinder/volume/drivers/dell_emc/powerflex/driver.py @@ -95,9 +95,11 @@ class PowerFlexDriver(driver.VolumeDriver): 3.5.6 - Fix for Bug #1897598 when volume can be migrated without conversion of its type. 3.5.7 - Report trim/discard support. + 3.5.8 - Added Cinder active/active support. """ - VERSION = "3.5.7" + VERSION = "3.5.8" + SUPPORTS_ACTIVE_ACTIVE = True # ThirdPartySystems wiki CI_WIKI_NAME = "DellEMC_PowerFlex_CI" @@ -429,6 +431,14 @@ class PowerFlexDriver(driver.VolumeDriver): self._get_client(secondary=True).remove_volume(remote_vol_id) def failover_host(self, context, volumes, secondary_id=None, groups=None): + active_backend_id, model_updates, group_update_list = ( + self.failover(context, volumes, secondary_id, groups)) + self.failover_completed(context, secondary_id) + return active_backend_id, model_updates, group_update_list + + def failover(self, context, volumes, secondary_id=None, groups=None): + """Like failover but for a host that is clustered.""" + LOG.info("Invoking failover with target %s.", secondary_id) if secondary_id not in self._available_failover_choices: msg = (_("Target %(target)s is not valid choice. " "Valid choices: %(choices)s.") % @@ -462,10 +472,35 @@ class PowerFlexDriver(driver.VolumeDriver): failover_status, is_failback) model_updates.append({"volume_id": volume.id, "updates": updates}) - self.active_backend_id = secondary_id - self.replication_enabled = is_failback + LOG.info("Failover host completed.") return secondary_id, model_updates, [] + def failover_completed(self, context, active_backend_id=None): + """This method is called after failover for clustered backends.""" + LOG.info("Invoking failover_completed with target %s.", + active_backend_id) + if (not active_backend_id + or active_backend_id + == manager.VolumeManager.FAILBACK_SENTINEL): + # failback operation + self.active_backend_id = manager.VolumeManager.FAILBACK_SENTINEL + self.replication_enabled = True + elif (active_backend_id == self.replication_device["backend_id"] + or active_backend_id == "failed over"): + # failover operation + self.active_backend_id = self.replication_device["backend_id"] + self.replication_enabled = False + else: + msg = f"Target {active_backend_id} is not valid." + LOG.error(msg) + raise exception.InvalidReplicationTarget(reason=msg) + + LOG.info("Failover completion completed: " + "active_backend_id = %s, " + "replication_enabled = %s.", + self.active_backend_id, + self.replication_enabled) + def _failover_replication_cg(self, rcg_name, is_failback): """Failover/failback Replication Consistency Group on storage backend. diff --git a/doc/source/configuration/block-storage/drivers/dell-emc-powerflex-driver.rst b/doc/source/configuration/block-storage/drivers/dell-emc-powerflex-driver.rst index f1d9b0057f7..e9db5b9a3d2 100644 --- a/doc/source/configuration/block-storage/drivers/dell-emc-powerflex-driver.rst +++ b/doc/source/configuration/block-storage/drivers/dell-emc-powerflex-driver.rst @@ -86,6 +86,8 @@ Supported operations * OpenStack replication v2.1 support +* Cinder volume active/active support + PowerFlex Block Storage driver configuration -------------------------------------------- diff --git a/doc/source/reference/support-matrix.ini b/doc/source/reference/support-matrix.ini index 4cf4cf65524..319d39515ff 100644 --- a/doc/source/reference/support-matrix.ini +++ b/doc/source/reference/support-matrix.ini @@ -986,7 +986,7 @@ driver.dell_emc_unity=missing driver.dell_emc_vmax_af=missing driver.dell_emc_vmax_3=missing driver.dell_emc_vnx=missing -driver.dell_emc_powerflex=missing +driver.dell_emc_powerflex=complete driver.dell_emc_xtremio=missing driver.fujitsu_eternus=missing driver.fungible=missing diff --git a/releasenotes/notes/bp-dell-powerflex-aa-828facb25b1fde63.yaml b/releasenotes/notes/bp-dell-powerflex-aa-828facb25b1fde63.yaml new file mode 100644 index 00000000000..db10085dbae --- /dev/null +++ b/releasenotes/notes/bp-dell-powerflex-aa-828facb25b1fde63.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Dell PowerFlex driver: + Enabled cinder volume active/active support. + This allows users to configure Dell PowerFlex backends + in cinder clustered environments.