]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: fs subvolume resize command
authorJos Collin <jcollin@redhat.com>
Wed, 28 Aug 2019 12:29:52 +0000 (17:59 +0530)
committerJos Collin <jcollin@redhat.com>
Thu, 24 Oct 2019 10:36:11 +0000 (16:06 +0530)
Fixes: https://tracker.ceph.com/issues/41182
Signed-off-by: Jos Collin <jcollin@redhat.com>
src/pybind/mgr/volumes/fs/subvolume.py
src/pybind/mgr/volumes/fs/volume.py
src/pybind/mgr/volumes/module.py

index 8f3c2b1ab5ef4c50428d92b0e9b7ab155acac160..d1426fd4831e09943b0e3ccfe45335eb40241a15 100644 (file)
@@ -143,6 +143,35 @@ class SubVolume(object):
         except cephfs.Error as e:
             raise VolumeException(-e.args[0], e.args[1])
 
+    def resize_subvolume(self, subvolpath, newsize, noshrink):
+        """
+        :param subvolpath: subvolume path
+        :param newsize: new size In bytes
+        :return: new quota size and used bytes as a tuple
+        """
+        if newsize <= 0:
+            raise VolumeException(-errno.EINVAL, "Provide a valid size")
+
+        try:
+            maxbytes = int(self.fs.getxattr(subvolpath, 'ceph.quota.max_bytes').decode('utf-8'))
+        except cephfs.NoData:
+            maxbytes = 0
+
+        subvolstat = self.fs.stat(subvolpath)
+        if newsize > 0 and newsize < subvolstat.st_size:
+            if noshrink:
+                raise VolumeException(-errno.EINVAL, "Can't resize the subvolume. The new size '{0}' would be lesser than the current "
+                                      "used size '{1}'".format(newsize, subvolstat.st_size))
+
+        if newsize == maxbytes:
+            return newsize, subvolstat.st_size
+
+        try:
+            self.fs.setxattr(subvolpath, 'ceph.quota.max_bytes', str(newsize).encode('utf-8'), 0)
+        except Exception as e:
+            raise VolumeException(-e.args[0], "Cannot set new size for the subvolume. '{0}'".format(e.args[1]))
+        return newsize, subvolstat.st_size
+
     def purge_subvolume(self, spec, should_cancel):
         """
         Finish clearing up a subvolume from the trash directory.
index 0187cc1b890278609652f8c331e49a384df0ef42..a37ec1affa8eddcc61661f201bc3edd076a5c0a8 100644 (file)
@@ -422,6 +422,33 @@ class VolumeClient(object):
             ret = self.volume_exception_to_retval(ve)
         return ret
 
+    @connection_pool_wrap
+    def resize_subvolume(self, fs_handle, **kwargs):
+        ret        = 0, "", ""
+        subvolname = kwargs['sub_name']
+        newsize    = kwargs['new_size']
+        groupname  = kwargs['group_name']
+        noshrink   = kwargs['no_shrink']
+
+        try:
+            with SubVolume(self.mgr, fs_handle) as sv:
+                spec = SubvolumeSpec(subvolname, groupname)
+                if not self.group_exists(sv, spec):
+                    raise VolumeException(
+                        -errno.ENOENT, "Subvolume group '{0}' not found, create it with " \
+                        "'ceph fs subvolumegroup create' before creating or resizing subvolumes".format(groupname))
+                subvolpath = sv.get_subvolume_path(spec)
+                if not subvolpath:
+                    raise VolumeException(
+                        -errno.ENOENT, "Subvolume '{0}' not found, create it with " \
+                        "'ceph fs subvolume create' before resizing subvolumes".format(subvolname))
+                nsize, usedbytes = sv.resize_subvolume(subvolpath, newsize, noshrink)
+                ret = 0, json.dumps([{'bytes_used': usedbytes},{'bytes_quota': nsize},
+                                     {'bytes_pcent': '{0:.2f}'.format((float(usedbytes) / nsize) * 100.0)}], indent=2), ""
+        except VolumeException as ve:
+            ret = self.volume_exception_to_retval(ve)
+        return ret
+
     @connection_pool_wrap
     def subvolume_getpath(self, fs_handle, **kwargs):
         ret        = None
index 0e710cfd5fc46c9a2d883dafdfc360ea8a2ccdb1..0268be566ce8810582c6024a3461a97962520619 100644 (file)
@@ -165,6 +165,16 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
                     "and optionally, in a specific subvolume group",
             'perm': 'rw'
         },
+        {
+            'cmd': 'fs subvolume resize '
+                   'name=vol_name,type=CephString '
+                   'name=sub_name,type=CephString '
+                   'name=new_size,type=CephInt,req=true '
+                   'name=group_name,type=CephString,req=false '
+                   'name=no_shrink,type=CephBool,req=false ',
+            'desc': "Resize a CephFS subvolume",
+            'perm': 'rw'
+        },
 
         # volume ls [recursive]
         # subvolume ls <volume>
@@ -314,3 +324,10 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
         return self.vc.list_subvolume_snapshots(None, vol_name=cmd['vol_name'],
                                                 sub_name=cmd['sub_name'],
                                                 group_name=cmd.get('group_name', None))
+
+    def _cmd_fs_subvolume_resize(self, inbuf, cmd):
+        return self.vc.resize_subvolume(None, vol_name=cmd['vol_name'],
+                                        sub_name=cmd['sub_name'],
+                                        new_size=cmd['new_size'],
+                                        group_name=cmd.get('group_name', None),
+                                        no_shrink=cmd.get('no_shrink', False))