From: Jos Collin Date: Wed, 28 Aug 2019 12:29:52 +0000 (+0530) Subject: mgr/volumes: fs subvolume resize command X-Git-Tag: v15.1.0~1076^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=efd5b1fad56da813aa4d548c9fe19eb3f20ec533;p=ceph.git mgr/volumes: fs subvolume resize command Fixes: https://tracker.ceph.com/issues/41182 Signed-off-by: Jos Collin --- diff --git a/src/pybind/mgr/volumes/fs/subvolume.py b/src/pybind/mgr/volumes/fs/subvolume.py index 8f3c2b1ab5ef..d1426fd4831e 100644 --- a/src/pybind/mgr/volumes/fs/subvolume.py +++ b/src/pybind/mgr/volumes/fs/subvolume.py @@ -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. diff --git a/src/pybind/mgr/volumes/fs/volume.py b/src/pybind/mgr/volumes/fs/volume.py index 0187cc1b8902..a37ec1affa8e 100644 --- a/src/pybind/mgr/volumes/fs/volume.py +++ b/src/pybind/mgr/volumes/fs/volume.py @@ -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 diff --git a/src/pybind/mgr/volumes/module.py b/src/pybind/mgr/volumes/module.py index 0e710cfd5fc4..0268be566ce8 100644 --- a/src/pybind/mgr/volumes/module.py +++ b/src/pybind/mgr/volumes/module.py @@ -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 @@ -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))