]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/vol: show clone source info in "subvolume info" cmd output
authorRishabh Dave <ridave@redhat.com>
Fri, 9 May 2025 16:40:47 +0000 (22:10 +0530)
committerJon <jonathan.bailey1@ibm.com>
Fri, 3 Oct 2025 13:31:26 +0000 (14:31 +0100)
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 <ridave@redhat.com>
(cherry picked from commit 0ef6da69d993ca58270010e0b458bad0dff29034)

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

index e73244985bb63257c6808d50e687b5dcb2d3daa0..5dc6d14b7348648ed0680cca08d662281f3b25d0 100644 (file)
@@ -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:
             casesensitive = True
 
-        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):
                 'casesensitive': casesensitive,
         }
 
+        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)
index ac7952726a362803e8f065ff127603788fea56d3..7b7c0751f9662bc2eee2e87477a69b246cf5a1b6 100644 (file)
@@ -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),