]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/vol: fix subvolume removal with retained snapshots when osd is full
authorneeraj pratap singh <neerajpratapsingh@li-ff7f0d4c-3462-11b2-a85c-d4004c0fa1a0.ibm.com>
Tue, 27 Aug 2024 09:38:41 +0000 (15:08 +0530)
committerneeraj pratap singh <neerajpratapsingh@li-ff7f0d4c-3462-11b2-a85c-d4004c0fa1a0.ibm.com>
Tue, 30 Sep 2025 10:38:08 +0000 (16:08 +0530)
The order of operation done for subvolume removal with retain-snapshot
option set to true, is reversed. The metadata is updated first
followed by a rename operation on the uuid directory. If the metadata
update operation fails, then the remove operations is failed thereby,
keeping the subvolume metadata consistent with the uuid path.

Fixes: https://tracker.ceph.com/issues/67330
Signed-off-by: Neeraj Pratap Singh <neesingh@redhat.com>
(cherry picked from commit ba199cf4c1865b7c6befe28175f2fd5ddd8a1b4d)

src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py

index a67c971b8dbf845d00c2278d4ea14e51c70cb02a..1313a2ba70141c45505cab0d9b49cc2e10e301d5 100644 (file)
@@ -341,14 +341,14 @@ class SubvolumeV2(SubvolumeV1):
         except cephfs.Error as e:
             raise VolumeException(-e.args[0], e.args[1])
 
-    def trash_incarnation_dir(self):
+    def trash_incarnation_dir(self, subvol_path):
         """rename subvolume (uuid component) to trash"""
         self.create_trashcan()
         try:
-            bname = os.path.basename(self.path)
+            bname = os.path.basename(subvol_path)
             tpath = os.path.join(self.trash_dir, bname)
-            log.debug("trash: {0} -> {1}".format(self.path, tpath))
-            self.fs.rename(self.path, tpath)
+            log.debug(f"trash: {subvol_path} -> {tpath}")
+            self.fs.rename(subvol_path, tpath)
             self._link_dir(tpath, bname)
         except cephfs.Error as e:
             raise VolumeException(-e.args[0], e.args[1])
@@ -378,13 +378,20 @@ class SubvolumeV2(SubvolumeV1):
                 self.auth_mdata_mgr.delete_subvolume_metadata_file(self.group.groupname, self.subvolname)
                 return
         if self.state != SubvolumeStates.STATE_RETAINED:
-            self.trash_incarnation_dir()
-            self.metadata_mgr.remove_section(MetadataManager.USER_METADATA_SECTION)
-            self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, "")
-            self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, SubvolumeStates.STATE_RETAINED.value)
-            self.metadata_mgr.flush()
-            # Delete the volume meta file, if it's not already deleted
-            self.auth_mdata_mgr.delete_subvolume_metadata_file(self.group.groupname, self.subvolname)
+            try:
+                # save subvol path for later use(renaming subvolume to trash) before deleting path section from .meta
+                subvol_path = self.path
+                self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, "")
+                self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, SubvolumeStates.STATE_RETAINED.value)
+                self.metadata_mgr.remove_section(MetadataManager.USER_METADATA_SECTION)
+                self.metadata_mgr.flush()
+                self.trash_incarnation_dir(subvol_path)
+                # Delete the volume meta file, if it's not already deleted
+                self.auth_mdata_mgr.delete_subvolume_metadata_file(self.group.groupname, self.subvolname)
+            except MetadataMgrException as e:
+                log.error(f"failed to write config: {e}")
+                raise VolumeException(e.args[0], e.args[1])
+
 
     def info(self):
         if self.state != SubvolumeStates.STATE_RETAINED: