From: Kotresh HR Date: Mon, 9 Aug 2021 10:05:16 +0000 (+0530) Subject: mgr/volumes: Fix permission during subvol creation with mode X-Git-Tag: v15.2.17~99^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F43224%2Fhead;p=ceph.git mgr/volumes: Fix permission during subvol creation with mode The subvolume creation with specific mode leads to creation of parent directories ('/volumes/_no_group') with the same mode if it's not already created. Fixed the same. Similarly, the subvolumegroup creation with specific mode leads to creation of parent directory ('/volumes') with same mode if it's not already created. Fixed the same. Fixes: https://tracker.ceph.com/issues/51870 Signed-off-by: Kotresh HR (cherry picked from commit 7440ef842a41eff3ac4751c487dacc5df2603095) Conflicts: qa/tasks/cephfs/test_volumes.py: The commmit d1d5d6188496cfdf712bc588f5dee9df8c989a38 is not present in octopus --- diff --git a/qa/tasks/cephfs/test_volumes.py b/qa/tasks/cephfs/test_volumes.py index 13eb2e641f2..caad215a56d 100644 --- a/qa/tasks/cephfs/test_volumes.py +++ b/qa/tasks/cephfs/test_volumes.py @@ -2120,17 +2120,20 @@ class TestVolumes(CephFSTestCase): expected_mode2 = "777" # create group + self._fs_cmd("subvolumegroup", "create", self.volname, group2, f"--mode={expected_mode2}") self._fs_cmd("subvolumegroup", "create", self.volname, group1) - self._fs_cmd("subvolumegroup", "create", self.volname, group2, "--mode", "777") group1_path = self._get_subvolume_group_path(self.volname, group1) group2_path = self._get_subvolume_group_path(self.volname, group2) + volumes_path = os.path.dirname(group1_path) # check group's mode actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', group1_path]).stdout.getvalue().strip() actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', group2_path]).stdout.getvalue().strip() + actual_mode3 = self.mount_a.run_shell(['stat', '-c' '%a', volumes_path]).stdout.getvalue().strip() self.assertEqual(actual_mode1, expected_mode1) self.assertEqual(actual_mode2, expected_mode2) + self.assertEqual(actual_mode3, expected_mode1) self._fs_cmd("subvolumegroup", "rm", self.volname, group1) self._fs_cmd("subvolumegroup", "rm", self.volname, group2) @@ -2160,6 +2163,36 @@ class TestVolumes(CephFSTestCase): # remove group self._fs_cmd("subvolumegroup", "rm", self.volname, subvolgroupname) + def test_subvolume_create_with_desired_mode(self): + subvol1 = self._generate_random_subvolume_name() + + # default mode + default_mode = "755" + # desired mode + desired_mode = "777" + + self._fs_cmd("subvolume", "create", self.volname, subvol1, "--mode", "777") + + subvol1_path = self._get_subvolume_path(self.volname, subvol1) + + # check subvolumegroup's mode + subvol_par_path = os.path.dirname(subvol1_path) + group_path = os.path.dirname(subvol_par_path) + actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', group_path]).stdout.getvalue().strip() + self.assertEqual(actual_mode1, default_mode) + # check /volumes mode + volumes_path = os.path.dirname(group_path) + actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', volumes_path]).stdout.getvalue().strip() + self.assertEqual(actual_mode2, default_mode) + # check subvolume's mode + actual_mode3 = self.mount_a.run_shell(['stat', '-c' '%a', subvol1_path]).stdout.getvalue().strip() + self.assertEqual(actual_mode3, desired_mode) + + self._fs_cmd("subvolume", "rm", self.volname, subvol1) + + # verify trash dir is clean + self._wait_for_trash_empty() + def test_subvolume_create_with_desired_mode_in_group(self): subvol1, subvol2, subvol3 = self._generate_random_subvolume_name(3) diff --git a/src/pybind/mgr/volumes/fs/fs_util.py b/src/pybind/mgr/volumes/fs/fs_util.py index 2adec83f5aa..c0cfef105aa 100644 --- a/src/pybind/mgr/volumes/fs/fs_util.py +++ b/src/pybind/mgr/volumes/fs/fs_util.py @@ -162,3 +162,15 @@ def get_ancestor_xattr(fs, path, attr): raise VolumeException(-e.args[0], e.args[1]) else: return get_ancestor_xattr(fs, os.path.split(path)[0], attr) + +def create_base_dir(fs, path, mode): + """ + Create volspec base/group directory if it doesn't exist + """ + try: + fs.stat(path) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + fs.mkdirs(path, mode) + else: + raise VolumeException(-e.args[0], e.args[1]) diff --git a/src/pybind/mgr/volumes/fs/operations/group.py b/src/pybind/mgr/volumes/fs/operations/group.py index bcf1bc2fd73..69e3959d7aa 100644 --- a/src/pybind/mgr/volumes/fs/operations/group.py +++ b/src/pybind/mgr/volumes/fs/operations/group.py @@ -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 +from ..fs_util import listdir, listsnaps, get_ancestor_xattr, create_base_dir from ..exception import VolumeException log = logging.getLogger(__name__) @@ -102,7 +102,11 @@ def create_group(fs, vol_spec, groupname, pool, mode, uid, gid): """ group = Group(fs, vol_spec, groupname) path = group.path - fs.mkdirs(path, mode) + vol_spec_base_dir = group.vol_spec.base_dir.encode('utf-8') + + # create vol_spec base directory with default mode(0o755) if it doesn't exist + create_base_dir(fs, vol_spec_base_dir, vol_spec.DEFAULT_MODE) + fs.mkdir(path, mode) try: if not pool: pool = get_ancestor_xattr(fs, path, "ceph.dir.layout.pool") 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 b735ccd3a6f..b2aab046a20 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -18,7 +18,7 @@ from ..template import SubvolumeTemplate from ..snapshot_util import mksnap, rmsnap from ..access import allow_access, deny_access from ...exception import IndexException, OpSmException, VolumeException, MetadataMgrException, EvictionError -from ...fs_util import listsnaps, is_inherited_snap +from ...fs_util import listsnaps, is_inherited_snap, create_base_dir from ..template import SubvolumeOpType from ..group import Group from ..rankevicter import RankEvicter @@ -93,6 +93,8 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) try: + # create group directory with default mode(0o755) if it doesn't exist. + create_base_dir(self.fs, self.group.path, self.vol_spec.DEFAULT_MODE) # create directory and set attributes self.fs.mkdirs(subvol_path, mode) self.mark_subvolume() diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py index 1dd6f3fe3aa..f680c18adff 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -12,7 +12,7 @@ from .op_sm import SubvolumeOpSm from .subvolume_v1 import SubvolumeV1 from ..template import SubvolumeTemplate from ...exception import OpSmException, VolumeException, MetadataMgrException -from ...fs_util import listdir +from ...fs_util import listdir, create_base_dir from ..template import SubvolumeOpType log = logging.getLogger(__name__) @@ -167,6 +167,8 @@ class SubvolumeV2(SubvolumeV1): raise VolumeException(-errno.EAGAIN, "asynchronous purge of subvolume in progress") subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) try: + # create group directory with default mode(0o755) if it doesn't exist. + create_base_dir(self.fs, self.group.path, self.vol_spec.DEFAULT_MODE) self.fs.mkdirs(subvol_path, mode) self.mark_subvolume() attrs = { diff --git a/src/pybind/mgr/volumes/fs/vol_spec.py b/src/pybind/mgr/volumes/fs/vol_spec.py index e18ab069062..5ff983115c3 100644 --- a/src/pybind/mgr/volumes/fs/vol_spec.py +++ b/src/pybind/mgr/volumes/fs/vol_spec.py @@ -9,6 +9,8 @@ class VolSpec(object): DEFAULT_SUBVOL_PREFIX = "/volumes" # and the default namespace DEFAULT_NS_PREFIX = "fsvolumens_" + # default mode for subvol prefix and group + DEFAULT_MODE = 0o755 def __init__(self, snapshot_prefix, subvolume_prefix=None, pool_ns_prefix=None): self.snapshot_prefix = snapshot_prefix