]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.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)
committerRishabh Dave <ridave@redhat.com>
Wed, 23 Jul 2025 15:30:01 +0000 (21:00 +0530)
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)

Conflicts:
- src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py
  Main branch version of info() method had code to fetch value of xattr
  ceph.dir.normalization and ceph.dir.casesensitive. But that isn't the
  case in Squid branch's info() method leading to conflict.
- src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py
  Method get_clone_failure() in main branch is located in
  subvolume_v1.py but in squid it is located in async_cloner.py

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

index 0ff5a6786d3849f963d9fb716366f171d8af0b41..3c8008162291c11360b2ef7e7758a4ae996d7221 100644 (file)
@@ -84,10 +84,6 @@ def set_clone_state(fs_client, volspec, volname, groupname, subvolname, state):
     with open_at_volume(fs_client, volspec, volname, groupname, subvolname, SubvolumeOpType.CLONE_INTERNAL) as subvolume:
         subvolume.state = (state, True)
 
-def get_clone_source(clone_subvolume):
-    source = clone_subvolume._get_clone_source()
-    return (source['volume'], source.get('group', None), source['subvolume'], source['snapshot'])
-
 def get_next_state_on_error(errnum):
     if errnum == -errno.EINTR:
         next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE,
index 3aaf78e4648236715d704420acc1c732a071e97c..347ef1a62fa7adb2d9004fd52862d495e5b5039a 100644 (file)
@@ -415,6 +415,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))
@@ -452,7 +480,8 @@ class SubvolumeBase(object):
         except EarmarkException:
             earmark = ''
 
-        return {'path': subvolpath,
+        subvol_info = {
+                'path': subvolpath,
                 'type': etype.value,
                 'uid': int(st["uid"]),
                 'gid': int(st["gid"]),
@@ -472,6 +501,26 @@ class SubvolumeBase(object):
                 'state': self.state.value,
                 'earmark': earmark}
 
+        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 20f67a58e7d70b3f9a6ef89cc5a32317b0415eae..acf4aa3e0d33e1b400947b137bc6af57339890b4 100644 (file)
@@ -650,25 +650,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_failure(self):
         clone_failure = {
             'errno'     : self.metadata_mgr.get_option(MetadataManager.CLONE_FAILURE_SECTION, MetadataManager.CLONE_FAILURE_META_KEY_ERRNO),