From 550ec2c4a90e99e1fa635771b70fa0e80544290a Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Tue, 9 Sep 2025 16:33:35 +0530 Subject: [PATCH] mgr/volumes: allow --force to delete subvols even when UUID is missing Also, add test for the same. Fixes: https://tracker.ceph.com/issues/72955 Signed-off-by: Rishabh Dave --- qa/tasks/cephfs/test_volumes.py | 21 +++++++++++++++++++ .../fs/operations/versions/subvolume_v2.py | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/qa/tasks/cephfs/test_volumes.py b/qa/tasks/cephfs/test_volumes.py index b427d973523..8450850609e 100644 --- a/qa/tasks/cephfs/test_volumes.py +++ b/qa/tasks/cephfs/test_volumes.py @@ -10798,3 +10798,24 @@ class TestPerModuleFinsherThread(TestVolumesHelper): # verify trash dir is clean self._wait_for_trash_empty() + +class TestCorruptedSubvolumes(TestVolumesHelper): + ''' + Test that certain cases like subvolume deletion and clone cancellations and + deletions are handled well on a corrupted subvolume as well. + ''' + + def test_rm_subvol_with_missing_UUID_dir(self): + sv1 = 'sv1' + + self.run_ceph_cmd(f'fs subvolume create {self.volname} {sv1}') + + sv_path = self.get_ceph_cmd_stdout(f'fs subvolume getpath {self.volname} ' + f'{sv1}').strip()[1:] + sv_path = os.path.join(self.mount_a.hostfs_mntpt, sv_path) + self.mount_a.run_shell(f'sudo rmdir {sv_path}', omit_sudo=False) + + self.negtest_ceph_cmd(f'fs subvolume rm {self.volname} {sv1}', + retval=errno.ENOENT, + errmsgs='mount path missing for subvolume') + self.run_ceph_cmd(f'fs subvolume rm {self.volname} {sv1} --force') 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 d5680327f3d..40c2270af37 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -337,6 +337,11 @@ class SubvolumeV2(SubvolumeV1): raise VolumeException(-errno.ENOENT, "subvolume '{0}' does not exist".format(self.subvolname)) raise VolumeException(me.args[0], me.args[1]) except cephfs.ObjectNotFound: + if op_type == SubvolumeOpType.REMOVE_FORCE: + log.debug("since --force is passed, ignoring missing subvolume '" + f"path '{subvol_path}' for subvolume " + f"{self.subvolname}'") + return log.debug("missing subvolume path '{0}' for subvolume '{1}'".format(subvol_path, self.subvolname)) raise VolumeException(-errno.ENOENT, "mount path missing for subvolume '{0}'".format(self.subvolname)) except cephfs.Error as e: -- 2.47.3