From db8706aa68887a45f25340a62eaddf62c0ea4f46 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Fri, 15 May 2020 20:29:01 +0530 Subject: [PATCH] mgr/volumes: Fix subvolume create idempotency After subvolume is created, it can be resized using subvolume create command. But it was broken and the same is fixed. Fixes: https://tracker.ceph.com/issues/45398 Signed-off-by: Kotresh HR --- qa/tasks/cephfs/test_volumes.py | 18 ++++++++++++++++++ .../fs/operations/versions/subvolume_base.py | 8 ++++++-- .../fs/operations/versions/subvolume_v1.py | 4 ++-- src/pybind/mgr/volumes/fs/volume.py | 12 +++++++++--- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/qa/tasks/cephfs/test_volumes.py b/qa/tasks/cephfs/test_volumes.py index 681993527e539..8a60bf75e6f46 100644 --- a/qa/tasks/cephfs/test_volumes.py +++ b/qa/tasks/cephfs/test_volumes.py @@ -566,6 +566,24 @@ class TestVolumes(CephFSTestCase): # verify trash dir is clean self._wait_for_trash_empty() + def test_subvolume_create_idempotence_resize(self): + # create subvolume + subvolume = self._generate_random_subvolume_name() + self._fs_cmd("subvolume", "create", self.volname, subvolume) + + # try creating w/ same subvolume name with size -- should set quota + self._fs_cmd("subvolume", "create", self.volname, subvolume, "1000000000") + + # get subvolume metadata + subvol_info = json.loads(self._get_subvolume_info(self.volname, subvolume)) + self.assertEqual(subvol_info["bytes_quota"], 1000000000) + + # remove subvolume + self._fs_cmd("subvolume", "rm", self.volname, subvolume) + + # verify trash dir is clean + self._wait_for_trash_empty() + def test_subvolume_create_with_invalid_data_pool_layout(self): subvolume = self._generate_random_subvolume_name() data_pool = "invalid_pool" diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py index 9142262dd2df1..dd0aec4d68b1d 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py @@ -99,7 +99,7 @@ class SubvolumeBase(object): else: self.metadata_mgr = MetadataManager(self.fs, self.config_path, 0o640) - def _set_attrs(self, path, size, isolate_namespace, pool, uid, gid): + def set_attrs(self, path, size, isolate_namespace, pool, uid, gid): # set size if size is not None: try: @@ -130,7 +130,11 @@ class SubvolumeBase(object): # layout remains unset and will undesirably change with ancestor's # pool layout changes. xattr_key = 'ceph.dir.layout.pool' - xattr_val = get_ancestor_xattr(self.fs, path, "ceph.dir.layout.pool") + xattr_val = None + try: + self.fs.getxattr(path, 'ceph.dir.layout.pool').decode('utf-8') + except cephfs.NoData as e: + xattr_val = get_ancestor_xattr(self.fs, os.path.split(path)[0], "ceph.dir.layout.pool") if xattr_key and xattr_val: try: self.fs.setxattr(path, xattr_key, xattr_val.encode('utf-8'), 0) 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 d8e0e0137ae4f..15f8d8bea1132 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -44,7 +44,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): try: # create directory and set attributes self.fs.mkdirs(subvol_path, mode) - self._set_attrs(subvol_path, size, isolate_nspace, pool, uid, gid) + self.set_attrs(subvol_path, size, isolate_nspace, pool, uid, gid) # persist subvolume metadata qpath = subvol_path.decode('utf-8') @@ -89,7 +89,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): try: # create directory and set attributes self.fs.mkdirs(subvol_path, source_subvolume.mode) - self._set_attrs(subvol_path, None, None, pool, source_subvolume.uid, source_subvolume.gid) + self.set_attrs(subvol_path, None, None, pool, source_subvolume.uid, source_subvolume.gid) # persist subvolume metadata and clone source qpath = subvol_path.decode('utf-8') diff --git a/src/pybind/mgr/volumes/fs/volume.py b/src/pybind/mgr/volumes/fs/volume.py index ff2924bb57a18..dc7ce35494fec 100644 --- a/src/pybind/mgr/volumes/fs/volume.py +++ b/src/pybind/mgr/volumes/fs/volume.py @@ -132,14 +132,20 @@ class VolumeClient(CephfsClient): volname = kwargs['vol_name'] subvolname = kwargs['sub_name'] groupname = kwargs['group_name'] + size = kwargs['size'] + pool = kwargs['pool_layout'] + uid = kwargs['uid'] + gid = kwargs['gid'] try: with open_volume(self, volname) as fs_handle: with open_group(fs_handle, self.volspec, groupname) as group: try: - with open_subvol(fs_handle, self.volspec, group, subvolname): - # idempotent creation -- valid. - pass + with open_subvol(fs_handle, self.volspec, group, subvolname) as subvolume: + # idempotent creation -- valid. Attributes set is supported. + uid = uid if uid else subvolume.uid + gid = gid if gid else subvolume.gid + subvolume.set_attrs(subvolume.path, size, False, pool, uid, gid) except VolumeException as ve: if ve.errno == -errno.ENOENT: self._create_subvolume(fs_handle, volname, group, subvolname, **kwargs) -- 2.39.5