]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/mgr/rbd_support: check whether mirroring is enabled
authorRamana Raja <rraja@redhat.com>
Tue, 6 May 2025 00:07:18 +0000 (20:07 -0400)
committerRamana Raja <rraja@redhat.com>
Mon, 16 Jun 2025 17:44:38 +0000 (13:44 -0400)
... before fetching the mirroring mode of the image.

In the CreateSnapshotRequests class, which asynchronously issues mirror
snapshot creation requests, prevalidation includes checking that the
image is enabled for snapshot-based mirroring and is marked as primary.
Since mirroring mode can only be queried if mirroring is already
enabled, the code first fetches the image’s mirroring info to verify
that mirroring is enabled, and only then retrieves the mirroring mode.

Signed-off-by: Ramana Raja <rraja@redhat.com>
src/pybind/mgr/rbd_support/mirror_snapshot_schedule.py

index e5b19f36228d3a48f9bc221014c4c566f93e69a5..665fe1656c194645cc31ff71ef03480577503c6c 100644 (file)
@@ -113,95 +113,101 @@ class CreateSnapshotRequests:
             self.finish(image_spec)
             return
 
-        self.get_mirror_mode(image_spec, image)
+        self.get_mirror_info(image_spec, image)
 
-    def get_mirror_mode(self, image_spec: ImageSpec, image: rbd.Image) -> None:
+    def get_mirror_info(self, image_spec: ImageSpec, image: rbd.Image) -> None:
         pool_id, namespace, image_id = image_spec
 
-        self.log.debug("CreateSnapshotRequests.get_mirror_mode: {}/{}/{}".format(
+        self.log.debug("CreateSnapshotRequests.get_mirror_info: {}/{}/{}".format(
             pool_id, namespace, image_id))
 
-        def cb(comp: rados.Completion, mode: Optional[int]) -> None:
-            self.handle_get_mirror_mode(image_spec, image, comp, mode)
+        def cb(comp: rados.Completion, info: Optional[Dict[str, Union[str, int]]]) -> None:
+            self.handle_get_mirror_info(image_spec, image, comp, info)
 
         try:
-            image.aio_mirror_image_get_mode(cb)
+            image.aio_mirror_image_get_info(cb)
         except Exception as e:
             self.log.error(
-                "exception when getting mirror mode for {}/{}/{}: {}".format(
+                "exception when getting mirror info for {}/{}/{}: {}".format(
                     pool_id, namespace, image_id, e))
             self.close_image(image_spec, image)
 
-    def handle_get_mirror_mode(self,
+    def handle_get_mirror_info(self,
                                image_spec: ImageSpec,
                                image: rbd.Image,
                                comp: rados.Completion,
-                               mode: Optional[int]) -> None:
+                               info: Optional[Dict[str, Union[str, int]]]) -> None:
         pool_id, namespace, image_id = image_spec
 
         self.log.debug(
-            "CreateSnapshotRequests.handle_get_mirror_mode {}/{}/{}: r={} mode={}".format(
-                pool_id, namespace, image_id, comp.get_return_value(), mode))
+            "CreateSnapshotRequests.handle_get_mirror_info {}/{}/{}: r={} info={}".format(
+                pool_id, namespace, image_id, comp.get_return_value(), info))
 
-        if mode is None:
-            if comp.get_return_value() != -errno.ENOENT:
-                self.log.error(
-                    "error when getting mirror mode for {}/{}/{}: {}".format(
-                        pool_id, namespace, image_id, comp.get_return_value()))
+        if info is None:
+            self.log.error(
+                "error when getting mirror info for {}/{}/{}: {}".format(
+                    pool_id, namespace, image_id, comp.get_return_value()))
             self.close_image(image_spec, image)
             return
 
-        if mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT:
+        if info['state'] != rbd.RBD_MIRROR_IMAGE_ENABLED:
             self.log.debug(
-                "CreateSnapshotRequests.handle_get_mirror_mode: {}/{}/{}: {}".format(
+                "CreateSnapshotRequests.handle_get_mirror_info: {}/{}/{}: {}".format(
                     pool_id, namespace, image_id,
-                    "snapshot mirroring is not enabled"))
+                    "mirroring is not enabled"))
             self.close_image(image_spec, image)
             return
 
-        self.get_mirror_info(image_spec, image)
+        if not info['primary']:
+            self.log.debug(
+                "CreateSnapshotRequests.handle_get_mirror_info: {}/{}/{}: {}".format(
+                    pool_id, namespace, image_id,
+                    "is not primary"))
+            self.close_image(image_spec, image)
+            return
 
-    def get_mirror_info(self, image_spec: ImageSpec, image: rbd.Image) -> None:
+        self.get_mirror_mode(image_spec, image)
+
+    def get_mirror_mode(self, image_spec: ImageSpec, image: rbd.Image) -> None:
         pool_id, namespace, image_id = image_spec
 
-        self.log.debug("CreateSnapshotRequests.get_mirror_info: {}/{}/{}".format(
+        self.log.debug("CreateSnapshotRequests.get_mirror_mode: {}/{}/{}".format(
             pool_id, namespace, image_id))
 
-        def cb(comp: rados.Completion, info: Optional[Dict[str, Union[str, int]]]) -> None:
-            self.handle_get_mirror_info(image_spec, image, comp, info)
+        def cb(comp: rados.Completion, mode: Optional[int]) -> None:
+            self.handle_get_mirror_mode(image_spec, image, comp, mode)
 
         try:
-            image.aio_mirror_image_get_info(cb)
+            image.aio_mirror_image_get_mode(cb)
         except Exception as e:
             self.log.error(
-                "exception when getting mirror info for {}/{}/{}: {}".format(
+                "exception when getting mirror mode for {}/{}/{}: {}".format(
                     pool_id, namespace, image_id, e))
             self.close_image(image_spec, image)
 
-    def handle_get_mirror_info(self,
+    def handle_get_mirror_mode(self,
                                image_spec: ImageSpec,
                                image: rbd.Image,
                                comp: rados.Completion,
-                               info: Optional[Dict[str, Union[str, int]]]) -> None:
+                               mode: Optional[int]) -> None:
         pool_id, namespace, image_id = image_spec
 
         self.log.debug(
-            "CreateSnapshotRequests.handle_get_mirror_info {}/{}/{}: r={} info={}".format(
-                pool_id, namespace, image_id, comp.get_return_value(), info))
+            "CreateSnapshotRequests.handle_get_mirror_mode {}/{}/{}: r={} mode={}".format(
+                pool_id, namespace, image_id, comp.get_return_value(), mode))
 
-        if info is None:
-            if comp.get_return_value() != -errno.ENOENT:
-                self.log.error(
-                    "error when getting mirror info for {}/{}/{}: {}".format(
-                        pool_id, namespace, image_id, comp.get_return_value()))
+        if mode is None:
+            self.log.error(
+                "error when getting mirror mode for {}/{}/{}: {}".format(
+                    pool_id, namespace, image_id, comp.get_return_value()))
             self.close_image(image_spec, image)
             return
 
-        if not info['primary']:
+        if mode != rbd.RBD_MIRROR_IMAGE_MODE_SNAPSHOT:
             self.log.debug(
-                "CreateSnapshotRequests.handle_get_mirror_info: {}/{}/{}: {}".format(
+                "CreateSnapshotRequests.handle_get_mirror_mode: {}/{}/{}: {}".format(
                     pool_id, namespace, image_id,
-                    "is not primary"))
+                    "not enabled for snapshot mirroring"))
             self.close_image(image_spec, image)
             return