From 15a2ab4e263b86a77af42c88247a1cb5fb016f94 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 29 Mar 2022 10:37:36 +0530 Subject: [PATCH] mgr/volumes: Fix idempotent subvolume rm 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 Fixes: https://tracker.ceph.com/issues/54625 Signed-off-by: Kotresh HR --- qa/tasks/cephfs/test_volumes.py | 35 +++++++++++++++++++ .../fs/operations/versions/subvolume_v2.py | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/qa/tasks/cephfs/test_volumes.py b/qa/tasks/cephfs/test_volumes.py index e9d57a770bb73..5fed1bd59c5f5 100644 --- a/qa/tasks/cephfs/test_volumes.py +++ b/qa/tasks/cephfs/test_volumes.py @@ -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.""" diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py index a827bb7a00e5e..3971d31b1aab2 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -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 -- 2.39.5