mirror of
https://github.com/ceph/ceph
synced 2024-12-24 20:33:27 +00:00
mgr/volumes: add interface to check the presence of subvolumegroups/subvolumes
Fixes: https://tracker.ceph.com/issues/55821 Signed-off-by: Neeraj Pratap Singh <neesingh@redhat.com>
This commit is contained in:
parent
869c716e9c
commit
4eff1bb534
@ -88,6 +88,28 @@ def listdir(fs, dirpath, filter_entries=None):
|
||||
raise VolumeException(-e.args[0], e.args[1])
|
||||
return dirs
|
||||
|
||||
|
||||
def has_subdir(fs, dirpath, filter_entries=None):
|
||||
"""
|
||||
Check the presence of directory (only dirs) for a given path
|
||||
"""
|
||||
res = False
|
||||
if filter_entries is None:
|
||||
filter_entries = [b".", b".."]
|
||||
else:
|
||||
filter_entries.extend([b".", b".."])
|
||||
try:
|
||||
with fs.opendir(dirpath) as dir_handle:
|
||||
d = fs.readdir(dir_handle)
|
||||
while d:
|
||||
if (d.d_name not in filter_entries) and d.is_dir():
|
||||
res = True
|
||||
break
|
||||
d = fs.readdir(dir_handle)
|
||||
except cephfs.Error as e:
|
||||
raise VolumeException(-e.args[0], e.args[1])
|
||||
return res
|
||||
|
||||
def is_inherited_snap(snapname):
|
||||
"""
|
||||
Returns True if the snapname is inherited else False
|
||||
|
@ -8,7 +8,7 @@ import cephfs
|
||||
from .snapshot_util import mksnap, rmsnap
|
||||
from .pin_util import pin
|
||||
from .template import GroupTemplate
|
||||
from ..fs_util import listdir, listsnaps, get_ancestor_xattr, create_base_dir
|
||||
from ..fs_util import listdir, listsnaps, get_ancestor_xattr, create_base_dir, has_subdir
|
||||
from ..exception import VolumeException
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -64,6 +64,15 @@ class Group(GroupTemplate):
|
||||
return []
|
||||
raise
|
||||
|
||||
def has_subvolumes(self):
|
||||
try:
|
||||
return has_subdir(self.fs, self.path)
|
||||
except VolumeException as ve:
|
||||
# listing a default group when it's not yet created
|
||||
if ve.errno == -errno.ENOENT and self.is_default_group():
|
||||
return False
|
||||
raise
|
||||
|
||||
def pin(self, pin_type, pin_setting):
|
||||
return pin(self.fs, self.path, pin_type, pin_setting)
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
from .operations.index import Index
|
||||
from .operations.group import Group
|
||||
from .operations.trash import Trash
|
||||
from .operations.versions.subvolume_base import SubvolumeBase
|
||||
|
||||
|
||||
class VolSpec(object):
|
||||
"""
|
||||
specification of a "volume" -- base directory and various prefixes.
|
||||
@ -9,6 +15,8 @@ class VolSpec(object):
|
||||
DEFAULT_NS_PREFIX = "fsvolumens_"
|
||||
# default mode for subvol prefix and group
|
||||
DEFAULT_MODE = 0o755
|
||||
# internal directories
|
||||
INTERNAL_DIRS = [Group.NO_GROUP_NAME, Index.GROUP_NAME, Trash.GROUP_NAME, SubvolumeBase.LEGACY_CONF_DIR]
|
||||
|
||||
def __init__(self, snapshot_prefix, subvolume_prefix=None, pool_ns_prefix=None):
|
||||
self.snapshot_prefix = snapshot_prefix
|
||||
|
@ -1,13 +1,14 @@
|
||||
import json
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import cephfs
|
||||
|
||||
from mgr_util import CephfsClient
|
||||
|
||||
from .fs_util import listdir
|
||||
from .fs_util import listdir, has_subdir
|
||||
|
||||
from .operations.volume import create_volume, \
|
||||
delete_volume, rename_volume, list_volumes, open_volume, get_pool_names
|
||||
@ -466,6 +467,28 @@ class VolumeClient(CephfsClient["Module"]):
|
||||
ret = self.volume_exception_to_retval(ve)
|
||||
return ret
|
||||
|
||||
def subvolume_exists(self, **kwargs):
|
||||
volname = kwargs['vol_name']
|
||||
groupname = kwargs['group_name']
|
||||
ret = 0, "", ""
|
||||
volume_exists = False
|
||||
|
||||
try:
|
||||
with open_volume(self, volname) as fs_handle:
|
||||
volume_exists = True
|
||||
with open_group(fs_handle, self.volspec, groupname) as group:
|
||||
res = group.has_subvolumes()
|
||||
if res:
|
||||
ret = 0, "subvolume exists", ""
|
||||
else:
|
||||
ret = 0, "no subvolume exists", ""
|
||||
except VolumeException as ve:
|
||||
if volume_exists and ve.errno == -errno.ENOENT:
|
||||
ret = 0, "no subvolume exists", ""
|
||||
else:
|
||||
ret = self.volume_exception_to_retval(ve)
|
||||
return ret
|
||||
|
||||
### subvolume snapshot
|
||||
|
||||
def create_subvolume_snapshot(self, **kwargs):
|
||||
@ -864,6 +887,27 @@ class VolumeClient(CephfsClient["Module"]):
|
||||
ret = self.volume_exception_to_retval(ve)
|
||||
return ret
|
||||
|
||||
def subvolume_group_exists(self, **kwargs):
|
||||
volname = kwargs['vol_name']
|
||||
ret = 0, "", ""
|
||||
volume_exists = False
|
||||
|
||||
try:
|
||||
with open_volume(self, volname) as fs_handle:
|
||||
volume_exists = True
|
||||
res = has_subdir(fs_handle, self.volspec.base_dir, filter_entries=[
|
||||
dir.encode('utf-8') for dir in self.volspec.INTERNAL_DIRS])
|
||||
if res:
|
||||
ret = 0, "subvolumegroup exists", ""
|
||||
else:
|
||||
ret = 0, "no subvolumegroup exists", ""
|
||||
except VolumeException as ve:
|
||||
if volume_exists and ve.errno == -errno.ENOENT:
|
||||
ret = 0, "no subvolumegroup exists", ""
|
||||
else:
|
||||
ret = self.volume_exception_to_retval(ve)
|
||||
return ret
|
||||
|
||||
### group snapshot
|
||||
|
||||
def create_subvolume_group_snapshot(self, **kwargs):
|
||||
|
@ -111,6 +111,12 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
|
||||
'desc': "Resize a CephFS subvolume group",
|
||||
'perm': 'rw'
|
||||
},
|
||||
{
|
||||
'cmd': 'fs subvolumegroup exist '
|
||||
'name=vol_name,type=CephString ',
|
||||
'desc': "Check a volume for the existence of subvolumegroup",
|
||||
'perm': 'r'
|
||||
},
|
||||
{
|
||||
'cmd': 'fs subvolume ls '
|
||||
'name=vol_name,type=CephString '
|
||||
@ -210,6 +216,14 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
|
||||
"and optionally, in a specific subvolume group",
|
||||
'perm': 'r'
|
||||
},
|
||||
{
|
||||
'cmd': 'fs subvolume exist '
|
||||
'name=vol_name,type=CephString '
|
||||
'name=group_name,type=CephString,req=false ',
|
||||
'desc': "Check a volume for the existence of a subvolume, "
|
||||
"optionally in a specified subvolume group",
|
||||
'perm': 'r'
|
||||
},
|
||||
{
|
||||
'cmd': 'fs subvolume metadata set '
|
||||
'name=vol_name,type=CephString '
|
||||
@ -567,6 +581,10 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
|
||||
def _cmd_fs_subvolumegroup_ls(self, inbuf, cmd):
|
||||
return self.vc.list_subvolume_groups(vol_name=cmd['vol_name'])
|
||||
|
||||
@mgr_cmd_wrap
|
||||
def _cmd_fs_subvolumegroup_exist(self, inbuf, cmd):
|
||||
return self.vc.subvolume_group_exists(vol_name=cmd['vol_name'])
|
||||
|
||||
@mgr_cmd_wrap
|
||||
def _cmd_fs_subvolume_create(self, inbuf, cmd):
|
||||
"""
|
||||
@ -657,6 +675,11 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
|
||||
sub_name=cmd['sub_name'],
|
||||
group_name=cmd.get('group_name', None))
|
||||
|
||||
@mgr_cmd_wrap
|
||||
def _cmd_fs_subvolume_exist(self, inbuf, cmd):
|
||||
return self.vc.subvolume_exists(vol_name=cmd['vol_name'],
|
||||
group_name=cmd.get('group_name', None))
|
||||
|
||||
@mgr_cmd_wrap
|
||||
def _cmd_fs_subvolume_metadata_set(self, inbuf, cmd):
|
||||
return self.vc.set_user_metadata(vol_name=cmd['vol_name'],
|
||||
|
Loading…
Reference in New Issue
Block a user