From 52d97807ca11a8f29c648e29606326c0d9a0054e Mon Sep 17 00:00:00 2001 From: Simon Dodsley Date: Tue, 15 Feb 2022 23:45:48 -0500 Subject: [PATCH] PureStorage FlashArray: Add active/active replication This patch adds support for active/active replication in the FlashArray driver. failover_host has been split into two parts (failover and failover_completed) to allow all nodes in a cluster to properly switch between primary and secondary backends after a succesful failover or failback procedure. Change-Id: I94e9c1106d4be0049b98ec7131ec88c9f9a32588 --- cinder/tests/unit/volume/drivers/test_pure.py | 6 ++-- cinder/volume/drivers/pure.py | 31 ++++++++++++++++--- .../pure_aa_replication-e3f5f6666f0b0c43.yaml | 6 ++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/pure_aa_replication-e3f5f6666f0b0c43.yaml diff --git a/cinder/tests/unit/volume/drivers/test_pure.py b/cinder/tests/unit/volume/drivers/test_pure.py index 33b2485519e..5126339baaa 100644 --- a/cinder/tests/unit/volume/drivers/test_pure.py +++ b/cinder/tests/unit/volume/drivers/test_pure.py @@ -2881,7 +2881,7 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): array2.get_volume.return_value = REPLICATED_VOLUME_SNAPS context = mock.MagicMock() - new_active_id, volume_updates, __ = self.driver.failover_host( + new_active_id, volume_updates, __ = self.driver.failover( context, REPLICATED_VOLUME_OBJS, None, @@ -2959,7 +2959,7 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): {"name": sync_replicated_vol_name} ] - new_active_id, volume_updates, __ = self.driver.failover_host( + new_active_id, volume_updates, __ = self.driver.failover( context, [ not_replicated_vol, @@ -3022,7 +3022,7 @@ class PureBaseVolumeDriverTestCase(PureBaseSharedDriverTestCase): mock_get_array, array2.get_volume, self.async_array2.copy_volume], - self.driver.failover_host, + self.driver.failover, mock.Mock(), REPLICATED_VOLUME_OBJS, None ) diff --git a/cinder/volume/drivers/pure.py b/cinder/volume/drivers/pure.py index f56fcf5a08d..c4c815e760f 100644 --- a/cinder/volume/drivers/pure.py +++ b/cinder/volume/drivers/pure.py @@ -1929,6 +1929,31 @@ class PureBaseVolumeDriver(san.SanDriver): @pure_driver_debug_trace def failover_host(self, context, volumes, secondary_id=None, groups=None): + """Failover to replication target. + + This function combines calls to failover() and failover_completed() to + perform failover when Active/Active is not enabled. + """ + active_backend_id, volume_update_list, group_update_list = ( + self.failover(context, volumes, secondary_id, groups)) + self.failover_completed(context, secondary_id) + return active_backend_id, volume_update_list, group_update_list + + @pure_driver_debug_trace + def failover_completed(self, context, secondary_id=None): + """Failover to replication target.""" + LOG.info('Driver failover completion started.') + if secondary_id == 'default': + self._swap_replication_state(self._get_current_array(), + self._failed_over_primary_array, + failback=True) + else: + self._swap_replication_state(self._get_current_array(), + self._find_sync_failover_target()) + LOG.info('Driver failover completion completed.') + + @pure_driver_debug_trace + def failover(self, context, volumes, secondary_id=None, groups=None): """Failover backend to a secondary array This action will not affect the original volumes in any @@ -1964,9 +1989,6 @@ class PureBaseVolumeDriver(san.SanDriver): 'status': 'error', } }) - self._swap_replication_state(current_array, - self._failed_over_primary_array, - failback=True) return secondary_id, model_updates, [] else: msg = _('Unable to failback to "default", this can only be ' @@ -2037,7 +2059,6 @@ class PureBaseVolumeDriver(san.SanDriver): model_updates = self._sync_failover_host(volumes, secondary_array) current_array = self._get_current_array() - self._swap_replication_state(current_array, secondary_array) return secondary_array.backend_id, model_updates, [] @@ -2097,7 +2118,7 @@ class PureBaseVolumeDriver(san.SanDriver): if secondary_array in self._uniform_active_cluster_target_arrays: self._uniform_active_cluster_target_arrays.remove( secondary_array) - current_array.unform = True + current_array.uniform = True self._uniform_active_cluster_target_arrays.append(current_array) self._set_current_array(secondary_array) diff --git a/releasenotes/notes/pure_aa_replication-e3f5f6666f0b0c43.yaml b/releasenotes/notes/pure_aa_replication-e3f5f6666f0b0c43.yaml new file mode 100644 index 00000000000..2c7a2ca7277 --- /dev/null +++ b/releasenotes/notes/pure_aa_replication-e3f5f6666f0b0c43.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Pure Storage FlashArray driver: Enabled support for Active/Active + replication for the FlashArray driver. This allows users to configure + FlashArray backends in clustered environments.