librbd: extend internal API to clone from open parent image

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2016-05-25 17:36:06 -04:00
parent 5a26080447
commit bfaa112c30
3 changed files with 73 additions and 48 deletions

View File

@ -1232,7 +1232,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
r = opts.set(RBD_IMAGE_OPTION_STRIPE_COUNT, stripe_count);
assert(r == 0);
r = create(io_ctx, imgname, size, opts);
r = create(io_ctx, imgname, size, opts, "", "");
int r1 = opts.get(RBD_IMAGE_OPTION_ORDER, &order_);
assert(r1 == 0);
@ -1242,7 +1242,9 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
}
int create(IoCtx& io_ctx, const char *imgname, uint64_t size,
ImageOptions& opts)
ImageOptions& opts,
const std::string &non_primary_global_image_id,
const std::string &primary_mirror_uuid)
{
CephContext *cct = (CephContext *)io_ctx.cct();
ldout(cct, 10) << __func__ << " name=" << imgname << ", "
@ -1337,7 +1339,8 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
r = create_v2(io_ctx, imgname, bid, size, order, features, stripe_unit,
stripe_count, journal_order, journal_splay_width,
journal_pool, "", "");
journal_pool, non_primary_global_image_id,
primary_mirror_uuid);
}
int r1 = opts.set(RBD_IMAGE_OPTION_ORDER, order);
@ -1372,9 +1375,48 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
IoCtx& c_ioctx, const char *c_name, ImageOptions& c_opts)
{
CephContext *cct = (CephContext *)p_ioctx.cct();
ldout(cct, 20) << "clone " << &p_ioctx << " name " << p_name << " snap "
<< p_snap_name << " to child " << &c_ioctx << " name "
<< c_name << " opts = " << c_opts << dendl;
if (p_snap_name == NULL) {
lderr(cct) << "image to be cloned must be a snapshot" << dendl;
return -EINVAL;
}
// make sure parent snapshot exists
ImageCtx *p_imctx = new ImageCtx(p_name, "", p_snap_name, p_ioctx, true);
int r = p_imctx->state->open();
if (r < 0) {
lderr(cct) << "error opening parent image: "
<< cpp_strerror(-r) << dendl;
delete p_imctx;
return r;
}
r = clone(p_imctx, c_ioctx, c_name, c_opts, "", "");
int close_r = p_imctx->state->close();
if (r == 0 && close_r < 0) {
r = close_r;
}
if (r < 0) {
return r;
}
return 0;
}
int clone(ImageCtx *p_imctx, IoCtx& c_ioctx, const char *c_name,
ImageOptions& c_opts,
const std::string &non_primary_global_image_id,
const std::string &primary_mirror_uuid)
{
CephContext *cct = p_imctx->cct;
if (p_imctx->snap_id == CEPH_NOSNAP) {
lderr(cct) << "image to be cloned must be a snapshot" << dendl;
return -EINVAL;
}
ldout(cct, 20) << "clone " << &p_imctx->md_ctx << " name " << p_imctx->name
<< " snap " << p_imctx->snap_name << " to child " << &c_ioctx
<< " name " << c_name << " opts = " << c_opts << dendl;
bool default_format_set;
c_opts.is_set(RBD_IMAGE_OPTION_FORMAT, &default_format_set);
@ -1406,12 +1448,8 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
return -EEXIST;
}
if (p_snap_name == NULL) {
lderr(cct) << "image to be cloned must be a snapshot" << dendl;
return -EINVAL;
}
bool snap_protected;
uint64_t order;
uint64_t size;
uint64_t p_features;
@ -1419,23 +1457,11 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
librbd::NoOpProgressContext no_op;
ImageCtx *c_imctx = NULL;
map<string, bufferlist> pairs;
// make sure parent snapshot exists
ImageCtx *p_imctx = new ImageCtx(p_name, "", p_snap_name, p_ioctx, true);
r = p_imctx->state->open();
if (r < 0) {
lderr(cct) << "error opening parent image: "
<< cpp_strerror(-r) << dendl;
delete p_imctx;
return r;
}
parent_spec pspec(p_ioctx.get_id(), p_imctx->id,
p_imctx->snap_id);
parent_spec pspec(p_imctx->md_ctx.get_id(), p_imctx->id, p_imctx->snap_id);
if (p_imctx->old_format) {
lderr(cct) << "parent image must be in new format" << dendl;
r = -EINVAL;
goto err_close_parent;
return -EINVAL;
}
p_imctx->snap_lock.get_read();
@ -1446,20 +1472,18 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
if ((p_features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) {
lderr(cct) << "parent image must support layering" << dendl;
r = -ENOSYS;
goto err_close_parent;
return -ENOSYS;
}
if (r < 0) {
// we lost the race with snap removal?
lderr(cct) << "unable to locate parent's snapshot" << dendl;
goto err_close_parent;
return r;
}
if (!snap_protected) {
lderr(cct) << "parent snapshot must be protected" << dendl;
r = -EINVAL;
goto err_close_parent;
return -EINVAL;
}
if (use_p_features) {
@ -1471,10 +1495,11 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
c_opts.set(RBD_IMAGE_OPTION_ORDER, order);
}
r = create(c_ioctx, c_name, size, c_opts);
r = create(c_ioctx, c_name, size, c_opts, non_primary_global_image_id,
primary_mirror_uuid);
if (r < 0) {
lderr(cct) << "error creating child: " << cpp_strerror(r) << dendl;
goto err_close_parent;
return r;
}
c_imctx = new ImageCtx(c_name, "", NULL, c_ioctx, false);
@ -1509,7 +1534,8 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
goto err_remove_child;
}
r = cls_client::metadata_list(&p_ioctx, p_imctx->header_oid, "", 0, &pairs);
r = cls_client::metadata_list(&p_imctx->md_ctx, p_imctx->header_oid, "", 0,
&pairs);
if (r < 0 && r != -EOPNOTSUPP && r != -EIO) {
lderr(cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
goto err_remove_child;
@ -1523,11 +1549,6 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
ldout(cct, 2) << "done." << dendl;
r = c_imctx->state->close();
partial_r = p_imctx->state->close();
if (r == 0 && partial_r < 0) {
r = partial_r;
}
return r;
err_remove_child:
@ -1545,8 +1566,6 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
lderr(cct) << "Error removing failed clone: "
<< cpp_strerror(partial_r) << dendl;
}
err_close_parent:
p_imctx->state->close();
return r;
}
@ -2235,7 +2254,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
opts.set(RBD_IMAGE_OPTION_ORDER, order);
}
int r = create(dest_md_ctx, destname, src_size, opts);
int r = create(dest_md_ctx, destname, src_size, opts, "", "");
if (r < 0) {
lderr(cct) << "header creation failed" << dendl;
return r;

View File

@ -101,12 +101,14 @@ namespace librbd {
bool old_format, uint64_t features, int *order,
uint64_t stripe_unit, uint64_t stripe_count);
int create(IoCtx& io_ctx, const char *imgname, uint64_t size,
ImageOptions& opts);
ImageOptions& opts,
const std::string &non_primary_global_image_id,
const std::string &primary_mirror_uuid);
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,
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,
const std::string &primary_mirror_uuid);
int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snap_name,
@ -115,6 +117,10 @@ namespace librbd {
uint64_t stripe_unit, int stripe_count);
int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snap_name,
IoCtx& c_ioctx, const char *c_name, ImageOptions& c_opts);
int clone(ImageCtx *p_imctx, IoCtx& c_ioctx, const char *c_name,
ImageOptions& c_opts,
const std::string &non_primary_global_image_id,
const std::string &primary_mirror_uuid);
int rename(librados::IoCtx& io_ctx, const char *srcname, const char *dstname);
int info(ImageCtx *ictx, image_info_t& info, size_t image_size);
int get_old_format(ImageCtx *ictx, uint8_t *old);

View File

@ -313,7 +313,7 @@ namespace librbd {
{
TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
tracepoint(librbd, create4_enter, io_ctx.get_pool_name().c_str(), io_ctx.get_id(), name, size, opts.opts);
int r = librbd::create(io_ctx, name, size, opts);
int r = librbd::create(io_ctx, name, size, opts, "", "");
tracepoint(librbd, create4_exit, r);
return r;
}
@ -1625,7 +1625,7 @@ extern "C" int rbd_create4(rados_ioctx_t p, const char *name,
TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
tracepoint(librbd, create4_enter, io_ctx.get_pool_name().c_str(), io_ctx.get_id(), name, size, opts);
librbd::ImageOptions opts_(opts);
int r = librbd::create(io_ctx, name, size, opts_);
int r = librbd::create(io_ctx, name, size, opts_, "", "");
tracepoint(librbd, create4_exit, r);
return r;
}