return 0;
}
+int mirror_image_enable(CephContext *cct, librados::IoCtx &io_ctx,
+ const std::string &id,
+ const std::string &global_image_id) {
+ cls::rbd::MirrorImage mirror_image_internal;
+ int r = cls_client::mirror_image_get(&io_ctx, id, &mirror_image_internal);
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ if (mirror_image_internal.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) {
+ // mirroring is already enabled
+ return 0;
+ } else if (r != -ENOENT) {
+ lderr(cct) << "cannot enable mirroring: currently disabling" << dendl;
+ return -EINVAL;
+ }
+
+ mirror_image_internal.state =
+ cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
+ if (global_image_id.empty()) {
+ uuid_d uuid_gen;
+ uuid_gen.generate_random();
+ mirror_image_internal.global_image_id = uuid_gen.to_string();
+ } else {
+ mirror_image_internal.global_image_id = global_image_id;
+ }
+
+ r = cls_client::mirror_image_set(&io_ctx, id, mirror_image_internal);
+ if (r < 0) {
+ lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ ldout(cct, 20) << "image mirroring is enabled: global_id=" <<
+ mirror_image_internal.global_image_id << dendl;
+
+ return 0;
+}
+
int mirror_image_enable_internal(ImageCtx *ictx) {
CephContext *cct = ictx->cct;
return -EINVAL;
}
- cls::rbd::MirrorImage mirror_image_internal;
- r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
- &mirror_image_internal);
- if (r < 0 && r != -ENOENT) {
- lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
- return r;
- }
-
- if (mirror_image_internal.state ==
- cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED) {
- // mirroring is already enabled
- return 0;
- }
- else if (r != -ENOENT) {
- lderr(cct) << "cannot enable mirroring: mirroring image is in "
- "disabling state" << dendl;
- return -EINVAL;
- }
-
- mirror_image_internal.state =
- cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
-
- uuid_d uuid_gen;
- uuid_gen.generate_random();
- mirror_image_internal.global_image_id = uuid_gen.to_string();
-
- r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id,
- mirror_image_internal);
+ r = mirror_image_enable(cct, ictx->md_ctx, ictx->id, "");
if (r < 0) {
- lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
return r;
}
- ldout(cct, 20) << "image mirroring is enabled: global_id=" <<
- mirror_image_internal.global_image_id << dendl;
-
return 0;
}
int create_v2(IoCtx& io_ctx, const char *imgname, uint64_t bid, uint64_t size,
int order, uint64_t features, uint64_t stripe_unit,
uint64_t stripe_count, uint8_t journal_order,
- uint8_t journal_splay_width,
- const std::string &journal_pool)
+ uint8_t journal_splay_width, const std::string &journal_pool,
+ const std::string &non_primary_global_image_id)
{
ostringstream bid_ss;
uint32_t extra;
CephContext *cct = (CephContext *)io_ctx.cct();
file_layout_t layout;
+ bool force_non_primary = !non_primary_global_image_id.empty();
int r = validate_pool(io_ctx, cct);
if (r < 0) {
goto err_remove_object_map;
}
- r = Journal<>::create(io_ctx, id, journal_order, journal_splay_width,
- journal_pool);
+ rbd_mirror_mode_t mirror_mode;
+ r = librbd::mirror_mode_get(io_ctx, &mirror_mode);
if (r < 0) {
- lderr(cct) << "error creating journal: " << cpp_strerror(r) << dendl;
+ lderr(cct) << "error in retrieving pool mirroring status: "
+ << cpp_strerror(r) << dendl;
goto err_remove_object_map;
}
- rbd_mirror_mode_t mirror_mode;
- r = librbd::mirror_mode_get(io_ctx, &mirror_mode);
+ r = Journal<>::create(io_ctx, id, journal_order, journal_splay_width,
+ journal_pool, force_non_primary);
if (r < 0) {
- lderr(cct) << "error in retrieving pool mirroring status: "
- << cpp_strerror(r) << dendl;
+ lderr(cct) << "error creating journal: " << cpp_strerror(r) << dendl;
goto err_remove_object_map;
}
- if (mirror_mode == RBD_MIRROR_MODE_POOL) {
- ImageCtx *img_ctx = new ImageCtx("", id, nullptr, io_ctx, false);
- r = img_ctx->state->open();
- if (r < 0) {
- lderr(cct) << "error opening image: " << cpp_strerror(r) << dendl;
- delete img_ctx;
- goto err_remove_object_map;
- }
- r = mirror_image_enable_internal(img_ctx);
+ if (mirror_mode == RBD_MIRROR_MODE_POOL || force_non_primary) {
+ r = mirror_image_enable(cct, io_ctx, id, non_primary_global_image_id);
if (r < 0) {
lderr(cct) << "error enabling mirroring: " << cpp_strerror(r)
- << dendl;
- img_ctx->state->close();
- goto err_remove_object_map;
+ << dendl;
+ goto err_remove_journal;
}
- img_ctx->state->close();
}
-
+ } else if (force_non_primary) {
+ // journaling should have been enabled
+ assert(false);
}
ldout(cct, 2) << "done." << dendl;
return 0;
+ err_remove_journal:
+ if ((features & RBD_FEATURE_JOURNALING) != 0) {
+ remove_r = Journal<>::remove(io_ctx, id);
+ if (remove_r < 0) {
+ lderr(cct) << "error cleaning up journal after creation failed: "
+ << cpp_strerror(remove_r) << dendl;
+ }
+ }
+
err_remove_object_map:
if ((features & RBD_FEATURE_OBJECT_MAP) != 0) {
remove_r = ObjectMap::remove(io_ctx, id);
opts.get(RBD_IMAGE_OPTION_JOURNAL_POOL, &journal_pool);
r = create_v2(io_ctx, imgname, bid, size, order, features, stripe_unit,
- stripe_count, journal_order, journal_splay_width, journal_pool);
+ stripe_count, journal_order, journal_splay_width,
+ journal_pool, "");
}
int r1 = opts.set(RBD_IMAGE_OPTION_ORDER, order);
r = Journal<>::create(ictx->md_ctx, ictx->id, ictx->journal_order,
ictx->journal_splay_width,
- ictx->journal_pool);
+ ictx->journal_pool, false);
if (r < 0) {
lderr(cct) << "error creating image journal: " << cpp_strerror(r)
<< dendl;