From b3f1d2d183d330d80d4e539e3a038f30586a2de0 Mon Sep 17 00:00:00 2001 From: Ramana Raja Date: Mon, 5 May 2025 20:07:18 -0400 Subject: [PATCH] pybind/mgr/rbd_support: check whether mirroring is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit ... 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 --- .../rbd_support/mirror_snapshot_schedule.py | 82 ++++++++++--------- 1 file changed, 44 insertions(+), 38 deletions(-) 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 -- 2.39.5