]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: Remove stale snapshot user metadata
authorKotresh HR <khiremat@redhat.com>
Tue, 16 Aug 2022 11:41:33 +0000 (17:11 +0530)
committerKotresh HR <khiremat@redhat.com>
Thu, 1 Sep 2022 07:38:16 +0000 (13:08 +0530)
This patch adds the capability to remove the stale snapshot user
metadata while loading the subvolume if it is present. It can't
be done in 'SubvolumeBase.discover' since v1 and v2 snapshot paths
are different. This is done just after the discover before returning
the specific version object.

Fixes: https://tracker.ceph.com/issues/55976
Signed-off-by: Kotresh HR <khiremat@redhat.com>
(cherry picked from commit 65af2d123a1f1ef9c4b370e908ece588eec19a1f)

src/pybind/mgr/volumes/fs/operations/versions/__init__.py
src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py

index 3dcdd7c10ab1001af4929a2314bca860cd84bf31..544afa165f975c6d77d6c7d524986d7ebc6b2227 100644 (file)
@@ -95,7 +95,10 @@ class SubvolumeLoader(object):
             subvolume.discover()
             self.upgrade_to_v2_subvolume(subvolume)
             version = int(subvolume.metadata_mgr.get_global_option('version'))
-            return self._get_subvolume_version(version)(mgr, fs, vol_spec, group, subvolname, legacy=subvolume.legacy_mode)
+            subvolume_version_object = self._get_subvolume_version(version)(mgr, fs, vol_spec, group, subvolname, legacy=subvolume.legacy_mode)
+            subvolume_version_object.metadata_mgr.refresh()
+            subvolume_version_object.clean_stale_snapshot_metadata()
+            return subvolume_version_object
         except MetadataMgrException as me:
             if me.errno == -errno.ENOENT and upgrade:
                 self.upgrade_legacy_subvolume(fs, subvolume)
index 764f4bc25751a876a1607e67737f44bd5aee52df..718735d91b131a323a40e0382da4396b543c52c0 100644 (file)
@@ -4,6 +4,7 @@ import logging
 import sys
 import threading
 import configparser
+import re
 
 import cephfs
 
@@ -184,3 +185,16 @@ class MetadataManager(object):
         if not self.config.has_section(section):
             raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section))
         return item in [v[1] for v in self.config.items(section)]
+
+    def has_snap_metadata_section(self):
+        sections = self.config.sections()
+        r = re.compile('SNAP_METADATA_.*')
+        for section in sections:
+            if r.match(section):
+                return True
+        return False
+
+    def list_snaps_with_metadata(self):
+        sections = self.config.sections()
+        r = re.compile('SNAP_METADATA_.*')
+        return [section[len("SNAP_METADATA_"):] for section in sections if r.match(section)]
index 906b55e7b83dfe5b62884ea915da0dfbae9b6a5c..3bae0707a6a4ddbea111d60a3b861db373d8ee18 100644 (file)
@@ -136,6 +136,10 @@ class SubvolumeBase(object):
         """ Boolean declaring if subvolume can be purged """
         raise NotImplementedError
 
+    def clean_stale_snapshot_metadata(self):
+        """ Clean up stale snapshot metadata """
+        raise NotImplementedError
+
     def load_config(self):
         try:
             self.fs.stat(self.legacy_config_path)
index 0e2a64d48eac9d62ba624c4544d13400e654229f..b5a10dd6c7f61b6647463fc8fd39739d6306f764 100644 (file)
@@ -857,6 +857,22 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate):
                 return []
             raise
 
+    def clean_stale_snapshot_metadata(self):
+        """ Clean up stale snapshot metadata """
+        if self.metadata_mgr.has_snap_metadata_section():
+            snap_list = self.list_snapshots()
+            snaps_with_metadata_list = self.metadata_mgr.list_snaps_with_metadata()
+            for snap_with_metadata in snaps_with_metadata_list:
+                if snap_with_metadata.encode('utf-8') not in snap_list:
+                    try:
+                        self.metadata_mgr.remove_section(self.get_snap_section_name(snap_with_metadata))
+                        self.metadata_mgr.flush()
+                    except MetadataMgrException as me:
+                        log.error(f"Failed to remove stale snap metadata on snap={snap_with_metadata} "
+                                  f"subvol={self.subvol_name} group={self.group_name} reason={me.args[1]}, "
+                                  f"errno:{-me.args[0]}, {os.strerror(-me.args[0])}")
+                        pass
+
     def _add_snap_clone(self, track_id, snapname):
         self.metadata_mgr.add_section("clone snaps")
         self.metadata_mgr.update_section("clone snaps", track_id, snapname)