]> git-server-git.apps.pok.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>
Fri, 16 Sep 2022 07:12:39 +0000 (12:42 +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 654c3ccca6ea410a9268499960e298a5a1a05fe9..72fc45a420ae780bdf6bfa8a779d5c16f16f2c90 100644 (file)
@@ -131,6 +131,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)