From: Venky Shankar Date: Mon, 2 Dec 2019 08:00:30 +0000 (-0500) Subject: mgr/volumes: handle transient subvolume states X-Git-Tag: v15.1.1~578^2~9 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=461909be2edd2f691263785469e5fc90a82448e8;p=ceph-ci.git mgr/volumes: handle transient subvolume states Signed-off-by: Venky Shankar --- diff --git a/src/pybind/mgr/volumes/fs/operations/subvolume.py b/src/pybind/mgr/volumes/fs/operations/subvolume.py index 8c3db11c421..bfd9349bb77 100644 --- a/src/pybind/mgr/volumes/fs/operations/subvolume.py +++ b/src/pybind/mgr/volumes/fs/operations/subvolume.py @@ -61,7 +61,7 @@ def remove_subvol(fs, vol_spec, group, subvolname): subvolume.remove() @contextmanager -def open_subvol(fs, vol_spec, group, subvolname): +def open_subvol(fs, vol_spec, group, subvolname, need_complete=True, expected_types=[]): """ open a subvolume. This API is to be used as a context manager. @@ -69,8 +69,12 @@ def open_subvol(fs, vol_spec, group, subvolname): :param vol_spec: volume specification :param group: group object for the subvolume :param subvolname: subvolume name + :param need_complete: check if the subvolume is usable (since cloned subvolumes can + be in transient state). defaults to True. + :param expected_types: check if the subvolume is one the provided types. defaults to + all. :return: yields a subvolume object (subclass of SubvolumeTemplate) """ subvolume = loaded_subvolumes.get_subvolume_object(fs, vol_spec, group, subvolname) - subvolume.open() + subvolume.open(need_complete, expected_types) yield subvolume diff --git a/src/pybind/mgr/volumes/fs/operations/template.py b/src/pybind/mgr/volumes/fs/operations/template.py index c5ecf47e7e4..14785e18dba 100644 --- a/src/pybind/mgr/volumes/fs/operations/template.py +++ b/src/pybind/mgr/volumes/fs/operations/template.py @@ -38,7 +38,7 @@ class SubvolumeTemplate(object): def version(): return SubvolumeTemplate.VERSION - def open(self): + def open(self, need_complete=True, expected_types=[]): raise VolumeException(-errno.ENOTSUP, "operation not supported.") def create(self, size, isolate_nspace, pool, mode, uid, gid): diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py index 5a28f6292fa..026ed32489a 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -6,6 +6,7 @@ import logging import cephfs +from .metadata_manager import MetadataManager from .subvolume_base import SubvolumeBase from ..op_sm import OpSm from ..template import SubvolumeTemplate @@ -107,12 +108,21 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): e = VolumeException(-e.args[0], e.args[1]) raise e - def open(self): + def open(self, need_complete=True, expected_types=[]): try: self.metadata_mgr.refresh() subvol_path = self.path log.debug("refreshed metadata, checking subvolume path '{0}'".format(subvol_path)) st = self.fs.stat(subvol_path) + etype = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_TYPE) + if len(expected_types) and not etype in expected_types: + raise VolumeException(-errno.ENOTSUP, "subvolume '{0}' is not {1}".format( + self.subvolname, "a {0}".format(expected_types[0]) if len(expected_types) == 1 else \ + "one of types ({0})".format(",".join(expected_types)))) + if need_complete: + estate = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_STATE) + if not OpSm.is_final_state(estate): + raise VolumeException(-errno.EAGAIN, "subvolume '{0}' is not ready for use".format(self.subvolname)) self.uid = int(st.st_uid) self.gid = int(st.st_gid) self.mode = int(st.st_mode & ~stat.S_IFMT(st.st_mode))