mirror of
https://github.com/ceph/ceph
synced 2025-01-01 00:22:25 +00:00
librbd: support creating images with non-primary journals
When rbd-mirror initially creates a replicated image in the local pool, the journal should be flagged as non-primary to (1) prevent local ops againsts the image and (2) provide a clean chain of replicated tags. Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
f01efc8ce6
commit
7a3ffc9d70
@ -313,7 +313,7 @@ bool Journal<I>::is_journal_supported(I &image_ctx) {
|
||||
template <typename I>
|
||||
int Journal<I>::create(librados::IoCtx &io_ctx, const std::string &image_id,
|
||||
uint8_t order, uint8_t splay_width,
|
||||
const std::string &object_pool) {
|
||||
const std::string &object_pool, bool non_primary) {
|
||||
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
|
||||
ldout(cct, 5) << __func__ << ": image=" << image_id << dendl;
|
||||
|
||||
@ -341,12 +341,16 @@ int Journal<I>::create(librados::IoCtx &io_ctx, const std::string &image_id,
|
||||
}
|
||||
|
||||
// create tag class for this image's journal events
|
||||
bufferlist tag_data;
|
||||
::encode(journal::TagData(), tag_data);
|
||||
journal::TagData tag_data;
|
||||
tag_data.mirror_uuid = (!non_primary ? LOCAL_MIRROR_UUID :
|
||||
ORPHAN_MIRROR_UUID);
|
||||
|
||||
bufferlist tag_data_bl;
|
||||
::encode(tag_data, tag_data_bl);
|
||||
|
||||
C_SaferCond tag_ctx;
|
||||
cls::journal::Tag tag;
|
||||
journaler.allocate_tag(cls::journal::Tag::TAG_CLASS_NEW, tag_data,
|
||||
journaler.allocate_tag(cls::journal::Tag::TAG_CLASS_NEW, tag_data_bl,
|
||||
&tag, &tag_ctx);
|
||||
r = tag_ctx.wait();
|
||||
if (r < 0) {
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
static bool is_journal_supported(ImageCtxT &image_ctx);
|
||||
static int create(librados::IoCtx &io_ctx, const std::string &image_id,
|
||||
uint8_t order, uint8_t splay_width,
|
||||
const std::string &object_pool);
|
||||
const std::string &object_pool, bool non_primary);
|
||||
static int remove(librados::IoCtx &io_ctx, const std::string &image_id);
|
||||
static int reset(librados::IoCtx &io_ctx, const std::string &image_id);
|
||||
|
||||
|
@ -200,6 +200,46 @@ int validate_mirroring_enabled(ImageCtx *ictx) {
|
||||
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;
|
||||
|
||||
@ -224,42 +264,11 @@ int mirror_image_enable_internal(ImageCtx *ictx) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -969,8 +978,8 @@ remove_mirroring_image:
|
||||
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;
|
||||
@ -980,6 +989,7 @@ remove_mirroring_image:
|
||||
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) {
|
||||
@ -1069,44 +1079,46 @@ remove_mirroring_image:
|
||||
goto err_remove_object_map;
|
||||
}
|
||||
|
||||
rbd_mirror_mode_t mirror_mode;
|
||||
r = librbd::mirror_mode_get(io_ctx, &mirror_mode);
|
||||
if (r < 0) {
|
||||
lderr(cct) << "error in retrieving pool mirroring status: "
|
||||
<< cpp_strerror(r) << dendl;
|
||||
goto err_remove_object_map;
|
||||
}
|
||||
|
||||
r = Journal<>::create(io_ctx, id, journal_order, journal_splay_width,
|
||||
journal_pool);
|
||||
journal_pool, force_non_primary);
|
||||
if (r < 0) {
|
||||
lderr(cct) << "error creating journal: " << cpp_strerror(r) << dendl;
|
||||
goto err_remove_object_map;
|
||||
}
|
||||
|
||||
rbd_mirror_mode_t mirror_mode;
|
||||
r = librbd::mirror_mode_get(io_ctx, &mirror_mode);
|
||||
if (r < 0) {
|
||||
lderr(cct) << "error in retrieving pool mirroring status: "
|
||||
<< 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);
|
||||
@ -1274,7 +1286,8 @@ remove_mirroring_image:
|
||||
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);
|
||||
@ -1617,7 +1630,7 @@ remove_mirroring_image:
|
||||
|
||||
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;
|
||||
|
@ -96,6 +96,12 @@ namespace librbd {
|
||||
uint64_t stripe_unit, uint64_t stripe_count);
|
||||
int create(IoCtx& io_ctx, const char *imgname, uint64_t size,
|
||||
ImageOptions& opts);
|
||||
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,
|
||||
const std::string &non_primary_global_image_id);
|
||||
int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snap_name,
|
||||
IoCtx& c_ioctx, const char *c_name,
|
||||
uint64_t features, int *c_order,
|
||||
|
@ -49,11 +49,20 @@ struct C_CreateImage : public Context {
|
||||
// TODO: rbd-mirror should offer a feature mask capability
|
||||
RWLock::RLocker snap_locker(remote_image_ctx->snap_lock);
|
||||
int order = remote_image_ctx->order;
|
||||
r = librbd::create(local_io_ctx, local_image_name.c_str(),
|
||||
remote_image_ctx->size, false,
|
||||
remote_image_ctx->features, &order,
|
||||
remote_image_ctx->stripe_unit,
|
||||
remote_image_ctx->stripe_count);
|
||||
|
||||
CephContext *cct = reinterpret_cast<CephContext*>(local_io_ctx.cct());
|
||||
uint64_t journal_order = cct->_conf->rbd_journal_order;
|
||||
uint64_t journal_splay_width = cct->_conf->rbd_journal_splay_width;
|
||||
std::string journal_pool = cct->_conf->rbd_journal_pool;
|
||||
|
||||
r = librbd::create_v2(local_io_ctx, local_image_name.c_str(),
|
||||
reinterpret_cast<uint64_t>(this),
|
||||
remote_image_ctx->size, order,
|
||||
remote_image_ctx->features,
|
||||
remote_image_ctx->stripe_unit,
|
||||
remote_image_ctx->stripe_count,
|
||||
journal_order, journal_splay_width, journal_pool,
|
||||
"global-image-id");
|
||||
on_finish->complete(r);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user