From: Mykola Golub Date: Wed, 13 Nov 2019 16:24:48 +0000 (+0000) Subject: librbd: API method to get mirror image mode X-Git-Tag: v15.1.0~565^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3a1361ba690f18aaf49906f5151769e911243408;p=ceph.git librbd: API method to get mirror image mode Signed-off-by: Mykola Golub --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index c5bdd8ae838e..a53e2c448fb7 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -171,6 +171,11 @@ typedef struct { #define RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST "mon_host" #define RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY "key" +typedef enum { + RBD_MIRROR_IMAGE_MODE_JOURNAL = 0, + RBD_MIRROR_IMAGE_MODE_SNAPSHOT = 1, +} rbd_mirror_image_mode_t; + typedef enum { RBD_MIRROR_IMAGE_DISABLING = 0, RBD_MIRROR_IMAGE_ENABLED = 1, @@ -1185,6 +1190,8 @@ CEPH_RBD_API int rbd_mirror_image_create_snapshot(rbd_image_t image, CEPH_RBD_API int rbd_mirror_image_get_info(rbd_image_t image, rbd_mirror_image_info_t *mirror_image_info, size_t info_size); +CEPH_RBD_API int rbd_mirror_image_get_mode(rbd_image_t image, + rbd_mirror_image_mode_t *mode); CEPH_RBD_API int rbd_mirror_image_get_global_status( rbd_image_t image, diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 40777b3af827..e53495e18427 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -108,6 +108,7 @@ namespace librbd { time_t last_seen; } mirror_peer_site_t; + typedef rbd_mirror_image_mode_t mirror_image_mode_t; typedef rbd_mirror_image_state_t mirror_image_state_t; typedef struct { @@ -735,6 +736,7 @@ public: int mirror_image_create_snapshot(uint64_t *snap_id); int mirror_image_get_info(mirror_image_info_t *mirror_image_info, size_t info_size); + int mirror_image_get_mode(mirror_image_mode_t *mode); int mirror_image_get_global_status( mirror_image_global_status_t *mirror_image_global_status, size_t status_size); @@ -746,6 +748,8 @@ public: int aio_mirror_image_demote(RBD::AioCompletion *c); int aio_mirror_image_get_info(mirror_image_info_t *mirror_image_info, size_t info_size, RBD::AioCompletion *c); + int aio_mirror_image_get_mode(mirror_image_mode_t *mode, + RBD::AioCompletion *c); int aio_mirror_image_get_global_status( mirror_image_global_status_t *mirror_image_global_status, size_t status_size, RBD::AioCompletion *c); diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index 76d0e7915ddf..8fb822a18beb 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -276,13 +276,16 @@ int list_mirror_images(librados::IoCtx& io_ctx, struct C_ImageGetInfo : public Context { mirror_image_info_t *mirror_image_info; + mirror_image_mode_t *mirror_image_mode; Context *on_finish; cls::rbd::MirrorImage mirror_image; mirror::PromotionState promotion_state = mirror::PROMOTION_STATE_PRIMARY; - C_ImageGetInfo(mirror_image_info_t *mirror_image_info, Context *on_finish) - : mirror_image_info(mirror_image_info), on_finish(on_finish) { + C_ImageGetInfo(mirror_image_info_t *mirror_image_info, + mirror_image_mode_t *mirror_image_mode, Context *on_finish) + : mirror_image_info(mirror_image_info), + mirror_image_mode(mirror_image_mode), on_finish(on_finish) { } void finish(int r) override { @@ -291,11 +294,19 @@ struct C_ImageGetInfo : public Context { return; } - mirror_image_info->global_id = mirror_image.global_image_id; - mirror_image_info->state = static_cast( - mirror_image.state); - mirror_image_info->primary = ( - promotion_state == mirror::PROMOTION_STATE_PRIMARY); + if (mirror_image_info != nullptr) { + mirror_image_info->global_id = mirror_image.global_image_id; + mirror_image_info->state = static_cast( + mirror_image.state); + mirror_image_info->primary = ( + promotion_state == mirror::PROMOTION_STATE_PRIMARY); + } + + if (mirror_image_mode != nullptr) { + *mirror_image_mode = + static_cast(mirror_image.mode); + } + on_finish->complete(0); } }; @@ -310,7 +321,7 @@ struct C_ImageGetGlobalStatus : public C_ImageGetInfo { const std::string &image_name, mirror_image_global_status_t *mirror_image_global_status, Context *on_finish) - : C_ImageGetInfo(&mirror_image_global_status->info, on_finish), + : C_ImageGetInfo(&mirror_image_global_status->info, nullptr, on_finish), image_name(image_name), mirror_image_global_status(mirror_image_global_status) { } @@ -611,7 +622,7 @@ void Mirror::image_get_info(I *ictx, mirror_image_info_t *mirror_image_info, CephContext *cct = ictx->cct; ldout(cct, 20) << "ictx=" << ictx << dendl; - auto ctx = new C_ImageGetInfo(mirror_image_info, on_finish); + auto ctx = new C_ImageGetInfo(mirror_image_info, nullptr, on_finish); auto req = mirror::GetInfoRequest::create(*ictx, &ctx->mirror_image, &ctx->promotion_state, ctx); @@ -630,6 +641,31 @@ int Mirror::image_get_info(I *ictx, mirror_image_info_t *mirror_image_info) { return 0; } +template +void Mirror::image_get_mode(I *ictx, mirror_image_mode_t *mode, + Context *on_finish) { + CephContext *cct = ictx->cct; + ldout(cct, 20) << "ictx=" << ictx << dendl; + + auto ctx = new C_ImageGetInfo(nullptr, mode, on_finish); + auto req = mirror::GetInfoRequest::create(*ictx, &ctx->mirror_image, + &ctx->promotion_state, + ctx); + req->send(); +} + +template +int Mirror::image_get_mode(I *ictx, mirror_image_mode_t *mode) { + C_SaferCond ctx; + image_get_mode(ictx, mode, &ctx); + + int r = ctx.wait(); + if (r < 0) { + return r; + } + return 0; +} + template void Mirror::image_get_global_status(I *ictx, mirror_image_global_status_t *status, diff --git a/src/librbd/api/Mirror.h b/src/librbd/api/Mirror.h index 6391b37fb8e2..c26c88d4b213 100644 --- a/src/librbd/api/Mirror.h +++ b/src/librbd/api/Mirror.h @@ -81,6 +81,9 @@ struct Mirror { static void image_get_info(ImageCtxT *ictx, mirror_image_info_t *mirror_image_info, Context *on_finish); + static int image_get_mode(ImageCtxT *ictx, mirror_image_mode_t *mode); + static void image_get_mode(ImageCtxT *ictx, mirror_image_mode_t *mode, + Context *on_finish); static int image_get_global_status(ImageCtxT *ictx, mirror_image_global_status_t *status); static void image_get_global_status(ImageCtxT *ictx, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 5a7c0a5a3a77..3238d7715710 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -2827,6 +2827,12 @@ namespace librbd { return librbd::api::Mirror<>::image_get_info(ictx, mirror_image_info); } + int Image::mirror_image_get_mode(mirror_image_mode_t *mode) { + ImageCtx *ictx = (ImageCtx *)ctx; + + return librbd::api::Mirror<>::image_get_mode(ictx, mode); + } + int Image::mirror_image_get_global_status( mirror_image_global_status_t *mirror_image_global_status, size_t status_size) { @@ -2912,6 +2918,16 @@ namespace librbd { return 0; } + int Image::aio_mirror_image_get_mode(mirror_image_mode_t *mode, + RBD::AioCompletion *c) { + ImageCtx *ictx = (ImageCtx *)ctx; + + librbd::api::Mirror<>::image_get_mode( + ictx, mode, new C_AioCompletion(ictx, librbd::io::AIO_TYPE_GENERIC, + get_aio_completion(c))); + return 0; + } + int Image::aio_mirror_image_get_global_status( mirror_image_global_status_t *status, size_t status_size, RBD::AioCompletion *c) { @@ -6196,6 +6212,14 @@ extern "C" int rbd_mirror_image_get_info(rbd_image_t image, return 0; } +extern "C" int rbd_mirror_image_get_mode(rbd_image_t image, + rbd_mirror_image_mode_t *mode) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + + return librbd::api::Mirror<>::image_get_mode(ictx, mode); +} + extern "C" int rbd_mirror_image_get_global_status( rbd_image_t image, rbd_mirror_image_global_status_t *status, size_t status_size) @@ -6302,6 +6326,18 @@ extern "C" int rbd_aio_mirror_image_get_info(rbd_image_t image, return 0; } +extern "C" int rbd_aio_mirror_image_get_mode(rbd_image_t image, + rbd_mirror_image_mode_t *mode, + rbd_completion_t c) { + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c; + + librbd::api::Mirror<>::image_get_mode( + ictx, mode, new C_AioCompletion(ictx, librbd::io::AIO_TYPE_GENERIC, + get_aio_completion(comp))); + return 0; +} + extern "C" int rbd_aio_mirror_image_get_global_status( rbd_image_t image, rbd_mirror_image_global_status_t *status, size_t status_size, rbd_completion_t c) { diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 2162fa60a3a7..6544bfbdf15b 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -187,6 +187,10 @@ cdef extern from "rbd/librbd.h" nogil: cdef char* _RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST "RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST" cdef char* _RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY "RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY" + ctypedef enum rbd_mirror_image_mode_t: + _RBD_MIRROR_IMAGE_MODE_JOURNAL "RBD_MIRROR_IMAGE_MODE_JOURNAL" + _RBD_MIRROR_IMAGE_MODE_SNAPSHOT "RBD_MIRROR_IMAGE_MODE_SNAPSHOT" + ctypedef enum rbd_mirror_image_state_t: _RBD_MIRROR_IMAGE_DISABLING "RBD_MIRROR_IMAGE_DISABLING" _RBD_MIRROR_IMAGE_ENABLED "RBD_MIRROR_IMAGE_ENABLED" @@ -587,6 +591,8 @@ cdef extern from "rbd/librbd.h" nogil: int rbd_mirror_image_get_info(rbd_image_t image, rbd_mirror_image_info_t *mirror_image_info, size_t info_size) + int rbd_mirror_image_get_mode(rbd_image_t image, + rbd_mirror_image_mode_t *mode) int rbd_mirror_image_get_global_status( rbd_image_t image, rbd_mirror_image_global_status_t *mirror_image_global_status, @@ -718,6 +724,9 @@ RBD_MIRROR_PEER_DIRECTION_RX = _RBD_MIRROR_PEER_DIRECTION_RX RBD_MIRROR_PEER_DIRECTION_TX = _RBD_MIRROR_PEER_DIRECTION_TX RBD_MIRROR_PEER_DIRECTION_RX_TX = _RBD_MIRROR_PEER_DIRECTION_RX_TX +RBD_MIRROR_IMAGE_MODE_JOURNAL = _RBD_MIRROR_IMAGE_MODE_JOURNAL +RBD_MIRROR_IMAGE_MODE_SNAPSHOT = _RBD_MIRROR_IMAGE_MODE_SNAPSHOT + RBD_MIRROR_IMAGE_DISABLING = _RBD_MIRROR_IMAGE_DISABLING RBD_MIRROR_IMAGE_ENABLED = _RBD_MIRROR_IMAGE_ENABLED RBD_MIRROR_IMAGE_DISABLED = _RBD_MIRROR_IMAGE_DISABLED @@ -4595,6 +4604,19 @@ written." % (self.name, ret, length)) free(c_info.global_id) return info + def mirror_image_get_mode(self): + """ + Get mirror mode for the image. + + :returns: int - mirror mode + """ + cdef rbd_mirror_image_mode_t c_mode + with nogil: + ret = rbd_mirror_image_get_mode(self.image, &c_mode) + if ret != 0: + raise make_ex(ret, 'error getting mirror mode for image %s' % self.name) + return int(c_mode) + def mirror_image_get_status(self): """ Get mirror status for the image. diff --git a/src/test/librbd/test_mirroring.cc b/src/test/librbd/test_mirroring.cc index 3770dfdaa19c..76518cda15ff 100644 --- a/src/test/librbd/test_mirroring.cc +++ b/src/test/librbd/test_mirroring.cc @@ -95,7 +95,8 @@ public: void check_mirror_image_enable( rbd_mirror_mode_t mirror_mode, uint64_t features, int expected_r, - rbd_mirror_image_state_t mirror_state) { + rbd_mirror_image_state_t mirror_state, + rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) { ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED)); @@ -112,6 +113,12 @@ public: ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); ASSERT_EQ(mirror_state, mirror_image.state); + if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) { + librbd::mirror_image_mode_t mode; + ASSERT_EQ(0, image.mirror_image_get_mode(&mode)); + ASSERT_EQ(mirror_image_mode, mode); + } + librbd::mirror_image_global_status_t status; ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status))); librbd::mirror_image_site_status_t local_status; @@ -227,7 +234,8 @@ public: void check_mirroring_on_update_features( uint64_t init_features, bool enable, bool enable_mirroring, uint64_t features, int expected_r, rbd_mirror_mode_t mirror_mode, - rbd_mirror_image_state_t mirror_state) { + rbd_mirror_image_state_t mirror_state, + rbd_mirror_image_mode_t mirror_image_mode = RBD_MIRROR_IMAGE_MODE_JOURNAL) { ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode)); @@ -246,6 +254,12 @@ public: ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image))); ASSERT_EQ(mirror_state, mirror_image.state); + if (mirror_image.state == RBD_MIRROR_IMAGE_ENABLED) { + librbd::mirror_image_mode_t mode; + ASSERT_EQ(0, image.mirror_image_get_mode(&mode)); + ASSERT_EQ(mirror_image_mode, mode); + } + librbd::mirror_image_global_status_t status; ASSERT_EQ(0, image.mirror_image_get_global_status(&status, sizeof(status))); librbd::mirror_image_site_status_t local_status; @@ -402,7 +416,7 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage) { features |= RBD_FEATURE_EXCLUSIVE_LOCK; features |= RBD_FEATURE_JOURNALING; check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0, - RBD_MIRROR_IMAGE_ENABLED); + RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL); } TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) { @@ -411,7 +425,7 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModePool) { features |= RBD_FEATURE_EXCLUSIVE_LOCK; features |= RBD_FEATURE_JOURNALING; check_mirror_image_enable(RBD_MIRROR_MODE_POOL, features, -EINVAL, - RBD_MIRROR_IMAGE_ENABLED); + RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_JOURNAL); } TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeDisabled) { @@ -554,13 +568,13 @@ TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutJournaling) { features |= RBD_FEATURE_OBJECT_MAP; features |= RBD_FEATURE_EXCLUSIVE_LOCK; check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0, - RBD_MIRROR_IMAGE_ENABLED); + RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT); } TEST_F(TestMirroring, EnableImageMirror_In_MirrorModeImage_WithoutExclusiveLock) { uint64_t features = 0; check_mirror_image_enable(RBD_MIRROR_MODE_IMAGE, features, 0, - RBD_MIRROR_IMAGE_ENABLED); + RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_MODE_SNAPSHOT); } TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) { @@ -630,7 +644,8 @@ TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage_MirroringEnabled) { init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; uint64_t features = RBD_FEATURE_JOURNALING; check_mirroring_on_update_features(init_features, true, true, features, - -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED); + -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED, + RBD_MIRROR_IMAGE_MODE_SNAPSHOT); } TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) { @@ -639,7 +654,8 @@ TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) { init_features |= RBD_FEATURE_EXCLUSIVE_LOCK; uint64_t features = RBD_FEATURE_JOURNALING; check_mirroring_on_update_features(init_features, true, false, features, 0, - RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED); + RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED, + RBD_MIRROR_IMAGE_MODE_JOURNAL); } TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) { @@ -659,7 +675,8 @@ TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) { init_features |= RBD_FEATURE_JOURNALING; uint64_t features = RBD_FEATURE_JOURNALING; check_mirroring_on_update_features(init_features, false, true, features, - -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED); + -EINVAL, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED, + RBD_MIRROR_IMAGE_MODE_JOURNAL); } TEST_F(TestMirroring, MirrorModeSet_DisabledMode_To_PoolMode) { @@ -1105,6 +1122,9 @@ TEST_F(TestMirroring, Snapshot) ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_IMAGE)); ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id)); ASSERT_EQ(0, image.mirror_image_enable()); + librbd::mirror_image_mode_t mode; + ASSERT_EQ(0, image.mirror_image_get_mode(&mode)); + ASSERT_EQ(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode); ASSERT_EQ(-EINVAL, image.mirror_image_create_snapshot(&snap_id)); std::string peer_uuid; ASSERT_EQ(0, m_rbd.mirror_peer_site_add(m_ioctx, &peer_uuid, diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index d16f5f590f80..3077a806b8b5 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -28,6 +28,7 @@ from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists, RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED, RBD_MIRROR_IMAGE_DISABLED, MIRROR_IMAGE_STATUS_STATE_UNKNOWN, + RBD_MIRROR_IMAGE_MODE_SNAPSHOT, RBD_LOCK_MODE_EXCLUSIVE, RBD_OPERATION_FEATURE_GROUP, RBD_SNAP_NAMESPACE_TYPE_TRASH, RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY, @@ -2060,6 +2061,8 @@ class TestMirroring(object): peer2_uuid = self.rbd.mirror_peer_add(ioctx, "cluster2", "client") self.rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE) self.image.mirror_image_enable() + mode = self.image.mirror_image_get_mode() + eq(RBD_MIRROR_IMAGE_MODE_SNAPSHOT, mode) snap_id = self.image.mirror_image_create_snapshot()