From: Ramana Raja Date: Mon, 5 May 2025 23:37:42 +0000 (-0400) Subject: librbd/mirror/PromoteRequest: return EINVAL X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eb19563c93f55757e9dabd050dfdd02233f33532;p=ceph.git 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 --- diff --git a/PendingReleaseNotes b/PendingReleaseNotes index 687f63434566..119284081d7e 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 b119e4edcd95..62b528390a3a 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 4d4b509c9a56..400756813f3a 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 810bc7ee2154..817f40d236a4 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()