]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: Fix idempotent subvolume rm 45683/head
authorKotresh HR <khiremat@redhat.com>
Tue, 29 Mar 2022 05:07:36 +0000 (10:37 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 29 Mar 2022 05:27:47 +0000 (10:57 +0530)
The subvolume deletion of a subvolume which is already deleted
with retain snapshots option fails with 'EAGAIN: clone in progress'
error. After subvolume deletion with retain snapshots, the subvolume
exists until the trash directory (resides inside subvolume) is
cleaned up. The subvolume deletion issued while the trash directory is not empty, should
pass. This patch fixes the same.

Credit: Issue discovery and fix suggestion to John Mulligan <jmulligan@redhat.com>
Fixes: https://tracker.ceph.com/issues/54625
Signed-off-by: Kotresh HR <khiremat@redhat.com>
qa/tasks/cephfs/test_volumes.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py

index e9d57a770bb73e3a70f074c3d0275c21f5b4808f..5fed1bd59c5f54c8fbfc5ce0904e0179d82ae99d 100644 (file)
@@ -2437,6 +2437,41 @@ class TestSubvolumes(TestVolumesHelper):
         # verify trash dir is clean
         self._wait_for_trash_empty()
 
+    def test_subvolume_retain_snapshot_rm_idempotency(self):
+        """
+        ensure subvolume deletion of a subvolume which is already deleted with retain snapshots option passes.
+        After subvolume deletion with retain snapshots, the subvolume exists until the trash directory (resides inside subvolume)
+        is cleaned up. The subvolume deletion issued while the trash directory is not empty, should pass and should
+        not error out with EAGAIN.
+        """
+        subvolume = self._generate_random_subvolume_name()
+        snapshot = self._generate_random_snapshot_name()
+
+        # create subvolume
+        self._fs_cmd("subvolume", "create", self.volname, subvolume, "--mode=777")
+
+        # do some IO
+        self._do_subvolume_io(subvolume, number_of_files=256)
+
+        # snapshot subvolume
+        self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot)
+
+        # remove with snapshot retention
+        self._fs_cmd("subvolume", "rm", self.volname, subvolume, "--retain-snapshots")
+
+        # remove snapshots (removes retained volume)
+        self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot)
+
+        # remove subvolume (check idempotency)
+        try:
+            self._fs_cmd("subvolume", "rm", self.volname, subvolume)
+        except CommandFailedError as ce:
+            if ce.exitstatus != errno.ENOENT:
+                self.fail(f"expected subvolume rm to pass with error: {os.strerror(ce.exitstatus)}")
+
+        # verify trash dir is clean
+        self._wait_for_trash_empty()
+
 
 class TestSubvolumeGroupSnapshots(TestVolumesHelper):
     """Tests for FS subvolume group snapshot operations."""
index a827bb7a00e5e78c811db83012e7f9ae70ff5d51..3971d31b1aab299ec8841308c2985380f32dd304 100644 (file)
@@ -352,7 +352,7 @@ class SubvolumeV2(SubvolumeV1):
         # machine which removes the entry from the index. Hence, it's safe to removed clone with
         # force option for both.
         acceptable_rm_clone_states = [SubvolumeStates.STATE_COMPLETE, SubvolumeStates.STATE_CANCELED,
-                                      SubvolumeStates.STATE_FAILED]
+                                      SubvolumeStates.STATE_FAILED, SubvolumeStates.STATE_RETAINED]
         if subvol_state not in acceptable_rm_clone_states:
             return False
         return True