From: Neeraj Pratap Singh Date: Mon, 18 Apr 2022 10:44:47 +0000 (+0530) Subject: mgr/volumes: Adding fs volume info command X-Git-Tag: v17.2.4~51^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9e3cff82d0134213ca77224288779eda47c99ab5;p=ceph.git mgr/volumes: Adding fs volume info command Fixes: https://tracker.ceph.com/issues/51434 Signed-off-by: Neeraj Pratap Singh (cherry picked from commit bf111a783e82d847651a54013ae2faab2a213eda) --- diff --git a/src/pybind/mgr/volumes/fs/operations/volume.py b/src/pybind/mgr/volumes/fs/operations/volume.py index 9ef06fd25e99..e6e374992fb0 100644 --- a/src/pybind/mgr/volumes/fs/operations/volume.py +++ b/src/pybind/mgr/volumes/fs/operations/volume.py @@ -1,6 +1,6 @@ import errno import logging -import sys +import os from typing import List, Tuple @@ -12,11 +12,11 @@ from .lock import GlobalLock from ..exception import VolumeException from ..fs_util import create_pool, remove_pool, rename_pool, create_filesystem, \ remove_filesystem, rename_filesystem, create_mds, volume_exists +from .trash import Trash from mgr_util import open_filesystem, CephfsConnectionException log = logging.getLogger(__name__) - def gen_pool_names(volname): """ return metadata and data pool name (from a filesystem/volume name) as a tuple @@ -55,6 +55,22 @@ def get_pool_names(mgr, volname): data_pools = [pools[id] for id in data_pool_ids] return metadata_pool, data_pools +def get_pool_ids(mgr, volname): + """ + return metadata and data pools (list) id of volume as a tuple + """ + fs_map = mgr.get("fs_map") + metadata_pool_id = None + data_pool_ids = [] # type: List[int] + for f in fs_map['filesystems']: + if volname == f['mdsmap']['fs_name']: + metadata_pool_id = f['mdsmap']['metadata_pool'] + data_pool_ids = f['mdsmap']['data_pools'] + break + if metadata_pool_id is None: + return None, None + return metadata_pool_id, data_pool_ids + def create_volume(mgr, volname, placement): """ create volume (pool, filesystem and mds) @@ -228,6 +244,20 @@ def list_volumes(mgr): return result +def get_pending_subvol_deletions_count(path): + """ + Get the number of pending subvolumes deletions. + """ + trashdir = os.path.join(path, Trash.GROUP_NAME) + try: + num_pending_subvol_del = len(os.listdir(trashdir)) + except OSError as e: + if e.errno == errno.ENOENT: + num_pending_subvol_del = 0 + + return {'pending_subvolume_deletions': num_pending_subvol_del} + + @contextmanager def open_volume(vc, volname): """ diff --git a/src/pybind/mgr/volumes/fs/volume.py b/src/pybind/mgr/volumes/fs/volume.py index faa969c52a72..9a1d663494ec 100644 --- a/src/pybind/mgr/volumes/fs/volume.py +++ b/src/pybind/mgr/volumes/fs/volume.py @@ -10,10 +10,10 @@ from mgr_util import CephfsClient from .fs_util import listdir, has_subdir -from .operations.volume import create_volume, \ - delete_volume, rename_volume, list_volumes, open_volume, get_pool_names from .operations.group import open_group, create_group, remove_group, \ open_group_unique, set_group_attrs +from .operations.volume import create_volume, delete_volume, rename_volume, \ + list_volumes, open_volume, get_pool_names, get_pool_ids, get_pending_subvol_deletions_count from .operations.subvolume import open_subvol, create_subvol, remove_subvol, \ create_clone from .operations.trash import Trash @@ -149,6 +149,51 @@ class VolumeClient(CephfsClient["Module"]): return rename_volume(self.mgr, volname, newvolname) + def volume_info(self, **kwargs): + ret = None + volname = kwargs['vol_name'] + + try: + with open_volume(self, volname) as fs_handle: + path = self.volspec.base_dir + vol_info_dict = {} + try: + st = fs_handle.statx(path.encode('utf-8'), cephfs.CEPH_STATX_SIZE, + cephfs.AT_SYMLINK_NOFOLLOW) + + usedbytes = st['size'] + vol_info_dict = get_pending_subvol_deletions_count(path) + vol_info_dict['used_size'] = int(usedbytes) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + pass + df = self.mgr.get("df") + pool_stats = dict([(p['id'], p['stats']) for p in df['pools']]) + osdmap = self.mgr.get("osd_map") + pools = dict([(p['pool'], p) for p in osdmap['pools']]) + metadata_pool_id, data_pool_ids = get_pool_ids(self.mgr, volname) + vol_info_dict["pools"] = {"metadata": [], "data": []} + for pool_id in [metadata_pool_id] + data_pool_ids: + if pool_id == metadata_pool_id: + pool_type = "metadata" + else: + pool_type = "data" + vol_info_dict["pools"][pool_type].append({ + 'name': pools[pool_id]['pool_name'], + 'used': pool_stats[pool_id]['bytes_used'], + 'avail': pool_stats[pool_id]['max_avail']}) + + mon_addr_lst = [] + mon_map_mons = self.mgr.get('mon_map')['mons'] + for mon in mon_map_mons: + ip_port = mon['addr'].split("/")[0] + mon_addr_lst.append(ip_port) + vol_info_dict["mon_addrs"] = mon_addr_lst + ret = 0, json.dumps(vol_info_dict, indent=4, sort_keys=True), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + ### subvolume operations def _create_subvolume(self, fs_handle, volname, group, subvolname, **kwargs): diff --git a/src/pybind/mgr/volumes/module.py b/src/pybind/mgr/volumes/module.py index 7f2e3993cdb0..752dde33e3e6 100644 --- a/src/pybind/mgr/volumes/module.py +++ b/src/pybind/mgr/volumes/module.py @@ -68,6 +68,12 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule): 'desc': "Rename a CephFS volume by passing --yes-i-really-mean-it flag", 'perm': 'rw' }, + { + 'cmd': 'fs volume info ' + 'name=vol_name,type=CephString ', + 'desc': "Get the information of a CephFS volume", + 'perm': 'r' + }, { 'cmd': 'fs subvolumegroup ls ' 'name=vol_name,type=CephString ', @@ -547,6 +553,10 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule): cmd['new_vol_name'], cmd.get('yes_i_really_mean_it', False)) + @mgr_cmd_wrap + def _cmd_fs_volume_info(self, inbuf, cmd): + return self.vc.volume_info(vol_name=cmd['vol_name']) + @mgr_cmd_wrap def _cmd_fs_subvolumegroup_create(self, inbuf, cmd): """