]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: Fix subvolume discover during upgrade
authorKotresh HR <khiremat@redhat.com>
Fri, 4 Feb 2022 09:25:03 +0000 (14:55 +0530)
committerDavid Galloway <dgallowa@redhat.com>
Thu, 21 Jul 2022 16:27:43 +0000 (12:27 -0400)
Fixes the subvolume discover to use the correct
metadata file after an upgrade from legacy subvolume
to v1. The fix makes sure, it doesn't use the
handcrafted metadata file placed in the subvolume
root of legacy subvolume.

Co-authored-by: Arthur Outhenin-Chalandre <arthur.outhenin-chalandre@cern.ch>
Co-authored-by: Dan van der Ster <daniel.vanderster@cern.ch>
Co-authored-by: Ramana Raja <rraja@redhat.com>
Signed-off-by: Kotresh HR <khiremat@redhat.com>
(cherry picked from commit 7eba9cab6cfb9a13a84062177d7a0fa228311e13)
(cherry picked from commit f8c04135150a7fb3c43607b43a8214e0d57547bc)

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

index 1b6c432783783f9b378a1b9409c51551880ec60c..cb3059e56534154304aac7034281a42c5e3f172d 100644 (file)
@@ -40,16 +40,17 @@ class MetadataManager(object):
     def refresh(self):
         fd = None
         conf_data = StringIO()
+        log.debug("opening config {0}".format(self.config_path))
         try:
-            log.debug("opening config {0}".format(self.config_path))
             fd = self.fs.open(self.config_path, os.O_RDONLY)
             while True:
                 data = self.fs.read(fd, -1, MetadataManager.MAX_IO_BYTES)
                 if not len(data):
                     break
                 conf_data.write(data.decode('utf-8'))
-            conf_data.seek(0)
-            self.config.readfp(conf_data)
+        except UnicodeDecodeError:
+            raise MetadataMgrException(-errno.EINVAL,
+                    "failed to decode, erroneous metadata config '{0}'".format(self.config_path))
         except cephfs.ObjectNotFound:
             raise MetadataMgrException(-errno.ENOENT, "metadata config '{0}' not found".format(self.config_path))
         except cephfs.Error as e:
@@ -58,6 +59,16 @@ class MetadataManager(object):
             if fd is not None:
                 self.fs.close(fd)
 
+        conf_data.seek(0)
+        try:
+            if sys.version_info >= (3, 2):
+                self.config.read_file(conf_data)
+            else:
+                self.config.readfp(conf_data)
+        except configparser.Error:
+            raise MetadataMgrException(-errno.EINVAL, "failed to parse, erroneous metadata config "
+                    "'{0}'".format(self.config_path))
+
     def flush(self):
         # cull empty sections
         for section in list(self.config.sections()):
index 7176653827353e85b2839bd17704f7f7599af6fa..54796b5ad367587fc40e758b183c59230e109eba 100644 (file)
@@ -5,6 +5,7 @@ import errno
 import logging
 from hashlib import md5
 from typing import Dict, Union
+from pathlib import Path
 
 import cephfs
 
@@ -123,6 +124,15 @@ class SubvolumeBase(object):
         raise NotImplementedError
 
     def load_config(self):
+        try:
+            self.fs.stat(self.legacy_config_path)
+            self.legacy_mode = True
+        except cephfs.Error as e:
+            pass
+
+        log.debug("loading config "
+                  "'{0}' [mode: {1}]".format(self.subvolname, "legacy"
+                                             if self.legacy_mode else "new"))
         if self.legacy_mode:
             self.metadata_mgr = MetadataManager(self.fs, self.legacy_config_path, 0o640)
         else:
@@ -276,8 +286,13 @@ class SubvolumeBase(object):
             self.fs.stat(self.base_path)
             self.metadata_mgr.refresh()
             log.debug("loaded subvolume '{0}'".format(self.subvolname))
+            subvolpath = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_PATH)
+            if not self.legacy_mode and self.base_path.decode('utf-8') != str(Path(subvolpath).parent):
+                raise MetadataMgrException(-errno.ENOENT, 'fabricated .meta')
         except MetadataMgrException as me:
-            if me.errno == -errno.ENOENT and not self.legacy_mode:
+            if me.errno in (-errno.ENOENT, -errno.EINVAL) and not self.legacy_mode:
+                log.warn("subvolume '{0}', {1}, "
+                          "assuming legacy_mode".format(self.subvolname, me.error_str))
                 self.legacy_mode = True
                 self.load_config()
                 self.discover()