]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: Fix permission during subvol creation with mode 43224/head
authorKotresh HR <khiremat@redhat.com>
Mon, 9 Aug 2021 10:05:16 +0000 (15:35 +0530)
committerKotresh HR <khiremat@redhat.com>
Mon, 20 Sep 2021 11:39:01 +0000 (17:09 +0530)
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 <khiremat@redhat.com>
(cherry picked from commit 7440ef842a41eff3ac4751c487dacc5df2603095)

Conflicts:
    qa/tasks/cephfs/test_volumes.py: The commmit d1d5d6188496cfdf712bc588f5dee9df8c989a38
is not present in octopus

qa/tasks/cephfs/test_volumes.py
src/pybind/mgr/volumes/fs/fs_util.py
src/pybind/mgr/volumes/fs/operations/group.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py
src/pybind/mgr/volumes/fs/vol_spec.py

index 13eb2e641f21ef6818b6f2f7ac9ef2a4490c26ee..caad215a56dcea65796954f3acddf1390b8b4aba 100644 (file)
@@ -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)
 
index 2adec83f5aafc4d0b6adcbf525bb407c6439576b..c0cfef105aaf075871c987f114188c7dea0e5254 100644 (file)
@@ -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])
index bcf1bc2fd73324ea8057dc2f51a5d9bdd61d1fc2..69e3959d7aa3d2ab684967854c9613382fe4d933 100644 (file)
@@ -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")
index b735ccd3a6f2cb5136c11b3f16094a633800eeb1..b2aab046a2053ccbf4c35485d654822399b70381 100644 (file)
@@ -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()
index 1dd6f3fe3aa82e6eb0d02ff45fd5c46d7845d368..f680c18adff098896550b7790d837a8bee4f6de1 100644 (file)
@@ -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 = {
index e18ab06906279488a7879204aa707cb89faa7753..5ff983115c3c1b81e227e3b922767ee4bfcb2e32 100644 (file)
@@ -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