From: Ramana Raja Date: Tue, 6 May 2025 00:07:18 +0000 (-0400) Subject: pybind/mgr/rbd_support: check whether mirroring is enabled X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b3f1d2d183d330d80d4e539e3a038f30586a2de0;p=ceph.git pybind/mgr/rbd_support: check whether mirroring is enabled ... 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 --- diff --git a/src/pybind/mgr/rbd_support/mirror_snapshot_schedule.py b/src/pybind/mgr/rbd_support/mirror_snapshot_schedule.py index e5b19f36228d3..665fe1656c194 100644 --- a/src/pybind/mgr/rbd_support/mirror_snapshot_schedule.py +++ b/src/pybind/mgr/rbd_support/mirror_snapshot_schedule.py @@ -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