#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,
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,
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 {
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);
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);
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 {
return;
}
- mirror_image_info->global_id = mirror_image.global_image_id;
- mirror_image_info->state = static_cast<rbd_mirror_image_state_t>(
- 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<rbd_mirror_image_state_t>(
+ mirror_image.state);
+ mirror_image_info->primary = (
+ promotion_state == mirror::PROMOTION_STATE_PRIMARY);
+ }
+
+ if (mirror_image_mode != nullptr) {
+ *mirror_image_mode =
+ static_cast<rbd_mirror_image_mode_t>(mirror_image.mode);
+ }
+
on_finish->complete(0);
}
};
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) {
}
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<I>::create(*ictx, &ctx->mirror_image,
&ctx->promotion_state,
ctx);
return 0;
}
+template <typename I>
+void Mirror<I>::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<I>::create(*ictx, &ctx->mirror_image,
+ &ctx->promotion_state,
+ ctx);
+ req->send();
+}
+
+template <typename I>
+int Mirror<I>::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 <typename I>
void Mirror<I>::image_get_global_status(I *ictx,
mirror_image_global_status_t *status,
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,
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) {
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) {
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)
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) {
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"
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,
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
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.
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));
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;
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));
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;
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) {
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) {
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) {
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) {
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) {
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) {
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,
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,
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()