From 6e8ed59a91934096a4ddc9b184ef50a633cbd1ec Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Fri, 9 Sep 2022 11:31:34 +0000 Subject: [PATCH] [NetApp] Consider last transfer size and error for replica state In order to determine replica state from snapmirror, in addition to existing check of last-transfer-end-timestamp', also add new checks of `last-transfer-size` and `last-transfer-error`. New config option `netapp_snapmirror_last_transfer_size_limit` added with default value of 1MB. The last-transfer-size above this value or presence of any last-transfer-error is considered as replica is out_of_sync. Closes-bug: #1989175 Change-Id: I6d038244493583cc943063b50d731b8c1ef5ed28 --- .../netapp/dataontap/cluster_mode/data_motion.py | 4 +++- .../netapp/dataontap/cluster_mode/lib_base.py | 16 ++++++++++++++++ manila/share/drivers/netapp/options.py | 6 ++++++ .../dataontap/cluster_mode/test_data_motion.py | 4 +++- .../dataontap/cluster_mode/test_lib_base.py | 9 +++++++++ ...error-for-replica-state-7ef49186a1b8a5a0.yaml | 10 ++++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/netapp-consider-last-transfer-size-error-for-replica-state-7ef49186a1b8a5a0.yaml diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/data_motion.py b/manila/share/drivers/netapp/dataontap/cluster_mode/data_motion.py index fb27994270..782defd757 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/data_motion.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/data_motion.py @@ -164,7 +164,9 @@ class DataMotionSession(object): 'mirror-state', 'source-vserver', 'source-volume', - 'last-transfer-end-timestamp']) + 'last-transfer-end-timestamp', + 'last-transfer-size', + 'last-transfer-error']) return snapmirrors def create_snapmirror(self, source_share_obj, dest_share_obj, diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py index d5677197d9..543aaba65c 100644 --- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py +++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py @@ -2650,6 +2650,22 @@ class NetAppCmodeFileStorageLibrary(object): .isoformat(), 3600))): return constants.REPLICA_STATE_OUT_OF_SYNC + replica_backend = share_utils.extract_host(replica['host'], + level='backend_name') + config = data_motion.get_backend_configuration(replica_backend) + config_size = (int(config.safe_get( + 'netapp_snapmirror_last_transfer_size_limit')) * units.Ki) + last_transfer_size = int(snapmirror.get('last-transfer-size', 0)) + if last_transfer_size > config_size: + return constants.REPLICA_STATE_OUT_OF_SYNC + + last_transfer_error = snapmirror.get('last-transfer-error', None) + if last_transfer_error: + LOG.debug('Found last-transfer-error: %(error)s for replica: ' + '%(replica)s.', {'replica': replica['id'], + 'error': last_transfer_error}) + return constants.REPLICA_STATE_OUT_OF_SYNC + # Check all snapshots exist snapshots = [snap['share_replica_snapshot'] for snap in share_snapshots] diff --git a/manila/share/drivers/netapp/options.py b/manila/share/drivers/netapp/options.py index fedb8d0237..ad64dd5a15 100644 --- a/manila/share/drivers/netapp/options.py +++ b/manila/share/drivers/netapp/options.py @@ -215,6 +215,12 @@ netapp_data_motion_opts = [ default=3600, # One Hour help='The maximum time in seconds to wait for a snapmirror ' 'release when breaking snapmirror relationships.'), + cfg.IntOpt('netapp_snapmirror_last_transfer_size_limit', + min=512, + default=1024, # One MB + help='This option set the last transfer size limit (in KB) ' + 'of snapmirror to decide whether replica is in sync or ' + 'out of sync.'), cfg.IntOpt('netapp_volume_move_cutover_timeout', min=0, default=3600, # One Hour, diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_data_motion.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_data_motion.py index d7c0107d35..8a8ac67d5b 100644 --- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_data_motion.py +++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_data_motion.py @@ -765,7 +765,9 @@ class NetAppCDOTDataMotionSessionTestCase(test.TestCase): 'mirror-state', 'source-vserver', 'source-volume', - 'last-transfer-end-timestamp'] + 'last-transfer-end-timestamp', + 'last-transfer-size', + 'last-transfer-error'] ) self.assertEqual(1, self.mock_dest_client.get_snapmirrors.call_count) diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py index a6d98e9482..f8949c4071 100644 --- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py +++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py @@ -4303,6 +4303,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.mock_object(self.library, '_is_readable_replica', mock.Mock(return_value=False)) + mock_backend_config = fake.get_config_cmode() + self.mock_object(data_motion, 'get_backend_configuration', + mock.Mock(return_value=mock_backend_config)) result = self.library.update_replica_state(None, [fake.SHARE], fake.SHARE, None, [], @@ -4346,6 +4349,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.mock_object(self.library, '_is_readable_replica', mock.Mock(return_value=False)) + mock_backend_config = fake.get_config_cmode() + self.mock_object(data_motion, 'get_backend_configuration', + mock.Mock(return_value=mock_backend_config)) result = self.library.update_replica_state(None, [fake.SHARE], fake.SHARE, None, snapshots, @@ -4374,6 +4380,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase): self.mock_object(self.library, '_is_readable_replica', mock.Mock(return_value=False)) + mock_backend_config = fake.get_config_cmode() + self.mock_object(data_motion, 'get_backend_configuration', + mock.Mock(return_value=mock_backend_config)) result = self.library.update_replica_state(None, [fake.SHARE], fake.SHARE, None, snapshots, diff --git a/releasenotes/notes/netapp-consider-last-transfer-size-error-for-replica-state-7ef49186a1b8a5a0.yaml b/releasenotes/notes/netapp-consider-last-transfer-size-error-for-replica-state-7ef49186a1b8a5a0.yaml new file mode 100644 index 0000000000..f63a97e158 --- /dev/null +++ b/releasenotes/notes/netapp-consider-last-transfer-size-error-for-replica-state-7ef49186a1b8a5a0.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + NetApp driver now considers ``last-transfer-size`` and + ``last-transfer-error`` fields of the snapmirror in addition to existing + ``last-transfer-end-timestamp`` to decide whether replica is in_sync or + out_of_sync. Added new config option + `netapp_snapmirror_last_transfer_size_limit` (default 1MB). If value of + `last-transfer-size` field is greater than config value or if + `last-transfer-error` field is present, then replica is out_of_sync.