From: Rishabh Dave Date: Fri, 9 May 2025 16:40:47 +0000 (+0530) Subject: mgr/vol: show clone source info in "subvolume info" cmd output X-Git-Tag: v20.2.1~38^2~30^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fbba4629cf6182fec31b8d3c391ed86b5b9f9d8f;p=ceph.git mgr/vol: show clone source info in "subvolume info" cmd output Include clone source information in output of "ceph fs subvolume info" command so that users can access this information conveniently. Fixes: https://tracker.ceph.com/issues/71266 Signed-off-by: Rishabh Dave (cherry picked from commit 0ef6da69d993ca58270010e0b458bad0dff29034) --- 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 11e78e77f8f3..1c5db5f0ac4b 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py @@ -442,6 +442,34 @@ class SubvolumeBase(object): except cephfs.Error as e: raise VolumeException(-e.args[0], e.args[1]) + def _get_clone_source(self): + try: + clone_source = { + 'volume' : self.metadata_mgr.get_option("source", "volume"), + 'subvolume': self.metadata_mgr.get_option("source", "subvolume"), + 'snapshot' : self.metadata_mgr.get_option("source", "snapshot"), + } + + try: + clone_source["group"] = self.metadata_mgr.get_option("source", "group") + except MetadataMgrException as me: + if me.errno == -errno.ENOENT: + pass + else: + raise + except MetadataMgrException as e: + if e.errno == -errno.ENOENT: + clone_source = {} + else: + raise VolumeException(-errno.EINVAL, + "error fetching subvolume metadata") + return clone_source + + def get_clone_source(self): + src = self._get_clone_source() + return (src['volume'], src.get('group', None), src['subvolume'], + src['snapshot']) + def info(self): subvolpath = (self.metadata_mgr.get_global_option( MetadataManager.GLOBAL_META_KEY_PATH)) @@ -494,7 +522,8 @@ class SubvolumeBase(object): except cephfs.NoData: case_insensitive = False - return {'path': subvolpath, + subvol_info = { + 'path': subvolpath, 'type': etype.value, 'uid': int(st["uid"]), 'gid': int(st["gid"]), @@ -517,6 +546,26 @@ class SubvolumeBase(object): 'case_insensitive': case_insensitive, } + subvol_src_info = self._get_clone_source() + if subvol_src_info: + if subvol_src_info.get('group', None) == None: + # group name won't be saved in .meta file in case it's + # default group + subvol_src_info['group'] = '_nogroup' + subvol_info['source'] = subvol_src_info + else: + # it could be that the clone was created in previous release of Ceph + # where its source info used to be deleted after cloning finishes. + # print "N/A" for such cases. + if self.subvol_type == SubvolumeTypes.TYPE_CLONE: + subvol_info['source'] = 'N/A' + else: + # only clones can have a source subvol, therefore don't even + # print "N/A" for source info if subvolume is not a clone. + pass + + return subvol_info + def set_user_metadata(self, keyname, value): try: self.metadata_mgr.add_section(MetadataManager.USER_METADATA_SECTION) diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py index e32ab1d1f501..972ca1954aac 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -652,30 +652,6 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): log.error(msg) raise EvictionError(msg) - def _get_clone_source(self): - try: - clone_source = { - 'volume' : self.metadata_mgr.get_option("source", "volume"), - 'subvolume': self.metadata_mgr.get_option("source", "subvolume"), - 'snapshot' : self.metadata_mgr.get_option("source", "snapshot"), - } - - try: - clone_source["group"] = self.metadata_mgr.get_option("source", "group") - except MetadataMgrException as me: - if me.errno == -errno.ENOENT: - pass - else: - raise - except MetadataMgrException: - raise VolumeException(-errno.EINVAL, "error fetching subvolume metadata") - return clone_source - - def get_clone_source(self): - src = self._get_clone_source() - return (src['volume'], src.get('group', None), src['subvolume'], - src['snapshot']) - def _get_clone_failure(self): clone_failure = { 'errno' : self.metadata_mgr.get_option(MetadataManager.CLONE_FAILURE_SECTION, MetadataManager.CLONE_FAILURE_META_KEY_ERRNO),