]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
pybind/mgr/volumes: block quiesce for critical .meta file
authorPatrick Donnelly <pdonnell@redhat.com>
Fri, 26 Jan 2024 21:37:15 +0000 (16:37 -0500)
committerPatrick Donnelly <pdonnell@redhat.com>
Fri, 22 Mar 2024 15:38:03 +0000 (11:38 -0400)
This file must remain accessible during quiesce to allow snapshots to be taken
on a subvolume.

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
(cherry picked from commit 0308f215ae7a6392de4dbd658c6d4334c1c98e9d)

src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py
src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py

index 8fbe177e5f4b56aa895dff8e6456b72ee07f6601..a8afcc368073bd42e00d218cfab52cfc43a2ad88 100644 (file)
@@ -69,6 +69,19 @@ class SubvolumeBase(object):
     def config_path(self):
         return os.path.join(self.base_path, b".meta")
 
+    def mark_meta(self):
+        """
+        Set "ceph.quiesce.block" flag on the .meta file inode.  It must remain
+        available while a subvolume is quiesced in order to allow some
+        interactions with the subvolume, snapshots in particular.
+        """
+        try:
+            self.fs.setxattr(self.config_path, 'ceph.quiesce.block', b'1', 0)
+        except cephfs.InvalidValue:
+            raise VolumeException(-errno.EINVAL, "invalid value specified for ceph.quiesce.block")
+        except cephfs.Error as e:
+            raise VolumeException(-e.args[0], e.args[1])
+
     @property
     def legacy_dir(self):
         return (os.path.join(self.vol_spec.base_dir.encode('utf-8'),
index 90f35a4c90b39e6523c9bd816bc8c1d9f7056ddb..5f81a63050534974655f647003c594d34284598b 100644 (file)
@@ -111,6 +111,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate):
             qpath = subvol_path.decode('utf-8')
             self.init_config(SubvolumeV1.VERSION, subvolume_type, qpath, initial_state)
             self.mark_subvolume()
+            self.mark_meta()
         except (VolumeException, MetadataMgrException, cephfs.Error) as e:
             try:
                 log.info("cleaning up subvolume with path: {0}".format(self.subvolname))
@@ -180,6 +181,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate):
             # create directory and set attributes
             self.fs.mkdirs(subvol_path, attrs.get("mode"))
             self.mark_subvolume()
+            self.mark_meta()
             self.set_attrs(subvol_path, attrs)
 
             # persist subvolume metadata and clone source
@@ -244,6 +246,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate):
             st = self.fs.stat(subvol_path)
             # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark
             self.mark_subvolume()
+            self.mark_meta()
 
             self.uid = int(st.st_uid)
             self.gid = int(st.st_gid)
index 55d7f945b7750631f7dadf4ad4b4ec6e0868f54a..089d5ae1c0183f4678460d208960419e715c3966 100644 (file)
@@ -189,6 +189,7 @@ class SubvolumeV2(SubvolumeV1):
 
             # Create the subvolume metadata file which manages auth-ids if it doesn't exist
             self.auth_mdata_mgr.create_subvolume_metadata_file(self.group.groupname, self.subvolname)
+            self.mark_meta()
         except (VolumeException, MetadataMgrException, cephfs.Error) as e:
             try:
                 self._remove_on_failure(subvol_path, retained)
@@ -243,6 +244,7 @@ class SubvolumeV2(SubvolumeV1):
                 self.metadata_mgr.init(SubvolumeV2.VERSION, subvolume_type.value, qpath, initial_state.value)
             self.add_clone_source(source_volname, source_subvolume, snapname)
             self.metadata_mgr.flush()
+            self.mark_meta()
         except (VolumeException, MetadataMgrException, cephfs.Error) as e:
             try:
                 self._remove_on_failure(subvol_path, retained)
@@ -300,6 +302,7 @@ class SubvolumeV2(SubvolumeV1):
             self.metadata_mgr.refresh()
             # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark
             self.mark_subvolume()
+            self.mark_meta()
 
             etype = self.subvol_type
             if op_type not in self.allowed_ops_by_type(etype):