Browse Source

Merge "Unmount NetApp active share after replica promote" into stable/rocky

stable/rocky
Zuul 1 month ago
parent
commit
8311587623

+ 25
- 0
manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py View File

@@ -1647,6 +1647,12 @@ class NetAppCmodeFileStorageLibrary(object):
1647 1647
                                                      replica_list)
1648 1648
                 new_replica_list.append(r)
1649 1649
 
1650
+        # Unmount the original active replica.
1651
+        orig_active_vserver = dm_session.get_vserver_from_share(
1652
+            orig_active_replica)
1653
+        self._unmount_orig_active_replica(orig_active_replica,
1654
+                                          orig_active_vserver)
1655
+
1650 1656
         self._handle_qos_on_replication_change(dm_session,
1651 1657
                                                new_active_replica,
1652 1658
                                                orig_active_replica,
@@ -1654,6 +1660,25 @@ class NetAppCmodeFileStorageLibrary(object):
1654 1660
 
1655 1661
         return new_replica_list
1656 1662
 
1663
+    def _unmount_orig_active_replica(self, orig_active_replica,
1664
+                                     orig_active_vserver=None):
1665
+        orig_active_replica_backend = (
1666
+            share_utils.extract_host(orig_active_replica['host'],
1667
+                                     level='backend_name'))
1668
+        orig_active_vserver_client = data_motion.get_client_for_backend(
1669
+            orig_active_replica_backend,
1670
+            vserver_name=orig_active_vserver)
1671
+        share_name = self._get_backend_share_name(
1672
+            orig_active_replica['id'])
1673
+        try:
1674
+            orig_active_vserver_client.unmount_volume(share_name,
1675
+                                                      force=True)
1676
+            LOG.info("Unmount of the original active replica %s successful.",
1677
+                     orig_active_replica['id'])
1678
+        except exception.StorageCommunicationException:
1679
+            LOG.exception("Could not unmount the original active replica %s.",
1680
+                          orig_active_replica['id'])
1681
+
1657 1682
     def _handle_qos_on_replication_change(self, dm_session, new_active_replica,
1658 1683
                                           orig_active_replica,
1659 1684
                                           share_server=None):

+ 42
- 3
manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py View File

@@ -2944,13 +2944,20 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2944 2944
                          mock.Mock(return_value=mock.Mock()))
2945 2945
         self.mock_object(self.library, '_create_export',
2946 2946
                          mock.Mock(return_value='fake_export_location'))
2947
+        self.mock_object(self.library, '_unmount_orig_active_replica')
2947 2948
         self.mock_object(self.library, '_handle_qos_on_replication_change')
2948 2949
 
2950
+        mock_dm_session = mock.Mock()
2951
+        self.mock_object(data_motion, "DataMotionSession",
2952
+                         mock.Mock(return_value=mock_dm_session))
2953
+        self.mock_object(mock_dm_session, 'get_vserver_from_share',
2954
+                         mock.Mock(return_value=fake.VSERVER1))
2955
+
2949 2956
         replicas = self.library.promote_replica(
2950 2957
             None, [self.fake_replica, self.fake_replica_2],
2951 2958
             self.fake_replica_2, [], share_server=None)
2952 2959
 
2953
-        self.mock_dm_session.change_snapmirror_source.assert_called_once_with(
2960
+        mock_dm_session.change_snapmirror_source.assert_called_once_with(
2954 2961
             self.fake_replica, self.fake_replica, self.fake_replica_2,
2955 2962
             mock.ANY
2956 2963
         )
@@ -2967,6 +2974,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2967 2974
                          actual_replica_2['export_locations'])
2968 2975
         self.assertEqual(constants.STATUS_ACTIVE,
2969 2976
                          actual_replica_2['access_rules_status'])
2977
+        self.library._unmount_orig_active_replica.assert_called_once_with(
2978
+            self.fake_replica, fake.VSERVER1)
2970 2979
         self.library._handle_qos_on_replication_change.assert_called_once()
2971 2980
 
2972 2981
     def test_promote_replica_destination_unreachable(self):
@@ -2977,6 +2986,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2977 2986
         self.mock_object(self.library,
2978 2987
                          '_get_helper',
2979 2988
                          mock.Mock(return_value=mock.Mock()))
2989
+        self.mock_object(self.library, '_unmount_orig_active_replica')
2980 2990
         self.mock_object(self.library, '_handle_qos_on_replication_change')
2981 2991
 
2982 2992
         self.mock_object(self.library, '_create_export',
@@ -2995,6 +3005,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
2995 3005
                          actual_replica['replica_state'])
2996 3006
         self.assertEqual(constants.STATUS_ERROR,
2997 3007
                          actual_replica['status'])
3008
+        self.assertFalse(
3009
+            self.library._unmount_orig_active_replica.called)
2998 3010
         self.assertFalse(
2999 3011
             self.library._handle_qos_on_replication_change.called)
3000 3012
 
@@ -3006,6 +3018,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3006 3018
                          '_get_vserver',
3007 3019
                          mock.Mock(return_value=(fake.VSERVER1,
3008 3020
                                                  mock.Mock())))
3021
+        self.mock_object(self.library, '_unmount_orig_active_replica')
3009 3022
         self.mock_object(self.library, '_handle_qos_on_replication_change')
3010 3023
         self.mock_object(self.library,
3011 3024
                          '_get_helper',
@@ -3013,12 +3026,17 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3013 3026
 
3014 3027
         self.mock_object(self.library, '_create_export',
3015 3028
                          mock.Mock(return_value='fake_export_location'))
3029
+        mock_dm_session = mock.Mock()
3030
+        self.mock_object(data_motion, "DataMotionSession",
3031
+                         mock.Mock(return_value=mock_dm_session))
3032
+        self.mock_object(mock_dm_session, 'get_vserver_from_share',
3033
+                         mock.Mock(return_value=fake.VSERVER1))
3016 3034
 
3017 3035
         replicas = self.library.promote_replica(
3018 3036
             None, [self.fake_replica, self.fake_replica_2, fake_replica_3],
3019 3037
             self.fake_replica_2, [], share_server=None)
3020 3038
 
3021
-        self.mock_dm_session.change_snapmirror_source.assert_has_calls([
3039
+        mock_dm_session.change_snapmirror_source.assert_has_calls([
3022 3040
             mock.call(fake_replica_3, self.fake_replica, self.fake_replica_2,
3023 3041
                       mock.ANY),
3024 3042
             mock.call(self.fake_replica, self.fake_replica,
@@ -3040,6 +3058,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3040 3058
             lambda x: x['id'] == fake_replica_3['id'], replicas))[0]
3041 3059
         self.assertEqual(constants.REPLICA_STATE_OUT_OF_SYNC,
3042 3060
                          actual_replica_3['replica_state'])
3061
+        self.library._unmount_orig_active_replica.assert_called_once_with(
3062
+            self.fake_replica, fake.VSERVER1)
3043 3063
         self.library._handle_qos_on_replication_change.assert_called_once()
3044 3064
 
3045 3065
     def test_promote_replica_with_access_rules(self):
@@ -3047,6 +3067,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3047 3067
                          '_get_vserver',
3048 3068
                          mock.Mock(return_value=(fake.VSERVER1,
3049 3069
                                                  mock.Mock())))
3070
+        self.mock_object(self.library, '_unmount_orig_active_replica')
3050 3071
         self.mock_object(self.library, '_handle_qos_on_replication_change')
3051 3072
         mock_helper = mock.Mock()
3052 3073
         self.mock_object(self.library,
@@ -3055,11 +3076,17 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3055 3076
         self.mock_object(self.library, '_create_export',
3056 3077
                          mock.Mock(return_value='fake_export_location'))
3057 3078
 
3079
+        mock_dm_session = mock.Mock()
3080
+        self.mock_object(data_motion, "DataMotionSession",
3081
+                         mock.Mock(return_value=mock_dm_session))
3082
+        self.mock_object(mock_dm_session, 'get_vserver_from_share',
3083
+                         mock.Mock(return_value=fake.VSERVER1))
3084
+
3058 3085
         replicas = self.library.promote_replica(
3059 3086
             None, [self.fake_replica, self.fake_replica_2],
3060 3087
             self.fake_replica_2, [fake.SHARE_ACCESS], share_server=None)
3061 3088
 
3062
-        self.mock_dm_session.change_snapmirror_source.assert_has_calls([
3089
+        mock_dm_session.change_snapmirror_source.assert_has_calls([
3063 3090
             mock.call(self.fake_replica, self.fake_replica,
3064 3091
                       self.fake_replica_2, mock.ANY)
3065 3092
         ], any_order=True)
@@ -3069,8 +3096,20 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
3069 3096
         mock_helper.update_access.assert_called_once_with(self.fake_replica_2,
3070 3097
                                                           share_name,
3071 3098
                                                           [fake.SHARE_ACCESS])
3099
+        self.library._unmount_orig_active_replica.assert_called_once_with(
3100
+            self.fake_replica, fake.VSERVER1)
3072 3101
         self.library._handle_qos_on_replication_change.assert_called_once()
3073 3102
 
3103
+    def test_unmount_orig_active_replica(self):
3104
+        self.mock_object(share_utils, 'extract_host', mock.Mock(
3105
+            return_value=fake.MANILA_HOST_NAME))
3106
+        self.mock_object(data_motion, 'get_client_for_backend')
3107
+        self.mock_object(self.library, '_get_backend_share_name', mock.Mock(
3108
+            return_value=fake.SHARE_NAME))
3109
+
3110
+        result = self.library._unmount_orig_active_replica(fake.SHARE)
3111
+        self.assertIsNone(result)
3112
+
3074 3113
     @ddt.data({'extra_specs': {'netapp:snapshot_policy': 'none'},
3075 3114
                'have_cluster_creds': True},
3076 3115
               # Test Case 2 isn't possible input

+ 5
- 0
releasenotes/notes/bug-1634278-unmount-orig-active-after-promote-8e24c099ddc1e564.yaml View File

@@ -0,0 +1,5 @@
1
+---
2
+fixes:
3
+  - The NetApp ONTAP driver is now fixed to unmount
4
+    the original active share volume after one of its
5
+    replica gets promoted.

Loading…
Cancel
Save