From: Kotresh HR Date: Fri, 22 Jul 2022 07:53:39 +0000 (+0530) Subject: mgr/volumes: Fix subvolume discover during upgrade X-Git-Tag: v18.0.0~441^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=373a04cf734d0ed7f4f2451d99826a9517cbe651;p=ceph.git mgr/volumes: Fix subvolume discover during upgrade 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 Co-authored-by: Dan van der Ster Co-authored-by: Ramana Raja Signed-off-by: Kotresh HR --- diff --git a/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py index ff040cf0010b9..8b89581a1c71e 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py @@ -45,16 +45,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: @@ -63,6 +64,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()): diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py index f7aa2ec81586b..6047516e4b8db 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py @@ -5,6 +5,7 @@ import errno import logging from hashlib import md5 from typing import Dict, Union +from pathlib import Path import cephfs @@ -128,6 +129,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, @@ -318,8 +328,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()