From eb19563c93f55757e9dabd050dfdd02233f33532 Mon Sep 17 00:00:00 2001 From: Ramana Raja Date: Mon, 5 May 2025 19:37:42 -0400 Subject: [PATCH] librbd/mirror/PromoteRequest: return EINVAL ... instead of ENOENT when mirroring is not enabled for the image. The PromoteRequest async state machine returns ENOENT when mirroring is not enabled for the image. Instead, make it return EINVAL similar to DemoteRequest's behavior, which is more appropriate. This also causes the public facing C, C++, and Python APIs that promote an image to return EINVAL or raise an equivalent exception when mirroring is not enabled for the image. Signed-off-by: Ramana Raja --- PendingReleaseNotes | 5 +++++ src/librbd/mirror/PromoteRequest.cc | 2 +- src/test/librbd/test_mirroring.cc | 4 ++++ src/test/pybind/test_rbd.py | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/PendingReleaseNotes b/PendingReleaseNotes index 687f634345662..119284081d7e3 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -160,6 +160,11 @@ C `rbd_mirror_image_get_mode()`, and Python `Image.mirror_image_get_mode()` -- will return EINVAL when mirroring is disabled. +* RBD: Promoting an image is invalid if the image is not enabled for mirroring. + The public APIs -- C++ `mirror_image_promote()`, + C `rbd_mirror_image_promote()`, and Python `Image.mirror_image_promote()` -- + will return EINVAL instead of ENOENT when mirroring is not enabled. + >=19.2.1 * CephFS: Command `fs subvolume create` now allows tagging subvolumes through option diff --git a/src/librbd/mirror/PromoteRequest.cc b/src/librbd/mirror/PromoteRequest.cc index b119e4edcd95b..62b528390a3ae 100644 --- a/src/librbd/mirror/PromoteRequest.cc +++ b/src/librbd/mirror/PromoteRequest.cc @@ -45,7 +45,7 @@ void PromoteRequest::handle_get_info(int r) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "r=" << r << dendl; - if (r < 0) { + if (r < 0 && r != -ENOENT) { lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r) << dendl; finish(r); diff --git a/src/test/librbd/test_mirroring.cc b/src/test/librbd/test_mirroring.cc index 4d4b509c9a560..400756813f3ab 100644 --- a/src/test/librbd/test_mirroring.cc +++ b/src/test/librbd/test_mirroring.cc @@ -1477,6 +1477,10 @@ TEST_F(TestMirroring, SnapshotPromoteDemote) ASSERT_EQ(0, image.mirror_image_demote()); ASSERT_EQ(0, image.mirror_image_promote(false)); + ASSERT_EQ(0, image.mirror_image_disable(false)); + ASSERT_EQ(-EINVAL, image.mirror_image_promote(false)); + ASSERT_EQ(-EINVAL, image.mirror_image_demote()); + ASSERT_EQ(0, image.close()); ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str())); ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer_uuid)); diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 810bc7ee21548..817f40d236a46 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -2679,6 +2679,9 @@ class TestMirroring(object): info = self.image.mirror_image_get_info() self.check_info(info, '', RBD_MIRROR_IMAGE_DISABLED, False) assert_raises(InvalidArgument, self.image.mirror_image_get_mode) + assert_raises(InvalidArgument, self.image.mirror_image_promote, False) + assert_raises(InvalidArgument, self.image.mirror_image_promote, True) + assert_raises(InvalidArgument, self.image.mirror_image_demote) self.image.mirror_image_enable() info = self.image.mirror_image_get_info() -- 2.39.5