]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: use CloneRequest in librbd::clone
authorDongsheng Yang <dongsheng.yang@easystack.cn>
Thu, 17 Nov 2016 09:23:03 +0000 (04:23 -0500)
committerDongsheng Yang <dongsheng.yang@easystack.cn>
Thu, 16 Mar 2017 12:18:32 +0000 (20:18 +0800)
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
src/librbd/internal.cc

index 6074711ef417df80f6a733e49203dae8bc2ad2e0..ff6dff41a6439cdefbf7999afd6b5d5d13d0dfcf 100644 (file)
@@ -33,6 +33,7 @@
 #include "librbd/api/Image.h"
 #include "librbd/exclusive_lock/AutomaticPolicy.h"
 #include "librbd/exclusive_lock/StandardPolicy.h"
+#include "librbd/image/CloneRequest.h"
 #include "librbd/image/CreateRequest.h"
 #include "librbd/image/RemoveRequest.h"
 #include "librbd/io/AioCompletion.h"
@@ -944,214 +945,19 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
             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);
-    if (!default_format_set) {
-      c_opts.set(RBD_IMAGE_OPTION_FORMAT, static_cast<uint64_t>(2));
-    }
-
-    uint64_t format = 0;
-    c_opts.get(RBD_IMAGE_OPTION_FORMAT, &format);
-    if (format < 2) {
-      lderr(cct) << "format 2 or later required for clone" << dendl;
-      return -EINVAL;
-    }
-
-    bool use_p_features = true;
-    uint64_t features;
-    if (c_opts.get(RBD_IMAGE_OPTION_FEATURES, &features) == 0) {
-      if (features & ~RBD_FEATURES_ALL) {
-       lderr(cct) << "librbd does not support requested features" << dendl;
-       return -ENOSYS;
-      }
-      use_p_features = false;
-    }
-
-    // make sure child doesn't already exist, in either format
-    int r = detect_format(c_ioctx, c_name, NULL, NULL);
-    if (r != -ENOENT) {
-      lderr(cct) << "rbd image " << c_name << " already exists" << dendl;
-      return -EEXIST;
-    }
-
-    bool snap_protected;
-
-    uint64_t order;
-    uint64_t size;
-    uint64_t p_features;
-    int partial_r;
-    librbd::NoOpProgressContext no_op;
-    ImageCtx *c_imctx = NULL;
-    map<string, bufferlist> pairs;
-    ParentSpec 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;
-      return -EINVAL;
-    }
-
-    p_imctx->snap_lock.get_read();
-    p_features = p_imctx->features;
-    size = p_imctx->get_image_size(p_imctx->snap_id);
-    r = p_imctx->is_snap_protected(p_imctx->snap_id, &snap_protected);
-    p_imctx->snap_lock.put_read();
-
-    if ((p_features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) {
-      lderr(cct) << "parent image must support layering" << dendl;
-      return -ENOSYS;
-    }
-
-    if (r < 0) {
-      // we lost the race with snap removal?
-      lderr(cct) << "unable to locate parent's snapshot" << dendl;
-      return r;
-    }
-
-    if (!snap_protected) {
-      lderr(cct) << "parent snapshot must be protected" << dendl;
-      return -EINVAL;
-    }
-
-    if ((p_features & RBD_FEATURE_JOURNALING) != 0) {
-      bool force_non_primary = !non_primary_global_image_id.empty();
-      bool is_primary;
-      int r = Journal<>::is_tag_owner(p_imctx, &is_primary);
-      if (r < 0) {
-       lderr(cct) << "failed to determine tag ownership: " << cpp_strerror(r)
-                  << dendl;
-       return r;
-      }
-      if (!is_primary && !force_non_primary) {
-       lderr(cct) << "parent is non-primary mirrored image" << dendl;
-       return -EINVAL;
-      }
-    }
-
-    if (use_p_features) {
-      features = p_features;
-    }
-
-    order = p_imctx->order;
-    if (c_opts.get(RBD_IMAGE_OPTION_ORDER, &order) != 0) {
-      c_opts.set(RBD_IMAGE_OPTION_ORDER, order);
-    }
+    CephContext *cct = (CephContext *)c_ioctx.cct();
 
-    if ((features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) {
-      lderr(cct) << "cloning image must support layering" << dendl;
-      return -ENOSYS;
-    }
-
-    c_opts.set(RBD_IMAGE_OPTION_FEATURES, features);
-    r = create(c_ioctx, c_name, size, c_opts, non_primary_global_image_id,
-               primary_mirror_uuid, true);
-    if (r < 0) {
-      lderr(cct) << "error creating child: " << cpp_strerror(r) << dendl;
-      return r;
-    }
-
-    c_imctx = new ImageCtx(c_name, "", NULL, c_ioctx, false);
-    r = c_imctx->state->open(false);
-    if (r < 0) {
-      lderr(cct) << "Error opening new image: " << cpp_strerror(r) << dendl;
-      goto err_remove;
-    }
-
-    r = cls_client::set_parent(&c_ioctx, c_imctx->header_oid, pspec, size);
-    if (r < 0) {
-      lderr(cct) << "couldn't set parent: " << cpp_strerror(r) << dendl;
-      goto err_close_child;
-    }
-
-    r = cls_client::add_child(&c_ioctx, RBD_CHILDREN, pspec, c_imctx->id);
-    if (r < 0) {
-      lderr(cct) << "couldn't add child: " << cpp_strerror(r) << dendl;
-      goto err_close_child;
-    }
-
-    r = p_imctx->state->refresh();
-    if (r == 0) {
-      p_imctx->snap_lock.get_read();
-      r = p_imctx->is_snap_protected(p_imctx->snap_id, &snap_protected);
-      p_imctx->snap_lock.put_read();
-    }
-    if (r < 0 || !snap_protected) {
-      // we lost the race with unprotect
-      r = -EINVAL;
-      goto err_remove_child;
-    }
-
-    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;
-    } else if (r == 0 && !pairs.empty()) {
-      r = cls_client::metadata_set(&c_ioctx, c_imctx->header_oid, pairs);
-      if (r < 0) {
-        lderr(cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
-        goto err_remove_child;
-      }
-    }
-
-    if (c_imctx->test_features(RBD_FEATURE_JOURNALING)) {
-      cls::rbd::MirrorMode mirror_mode_internal =
-        cls::rbd::MIRROR_MODE_DISABLED;
-      r = cls_client::mirror_mode_get(&c_imctx->md_ctx, &mirror_mode_internal);
-      if (r < 0 && r != -ENOENT) {
-        lderr(cct) << "failed to retrieve mirror mode: " << cpp_strerror(r)
-                   << dendl;
-        goto err_remove_child;
-      }
-
-      // enable mirroring now that clone has been fully created
-      if (mirror_mode_internal == cls::rbd::MIRROR_MODE_POOL ||
-          !non_primary_global_image_id.empty()) {
-        C_SaferCond ctx;
-        mirror::EnableRequest<ImageCtx> *req =
-          mirror::EnableRequest<ImageCtx>::create(c_imctx->md_ctx, c_imctx->id,
-                                                  non_primary_global_image_id,
-                                                  c_imctx->op_work_queue, &ctx);
-        req->send();
-
-        r = ctx.wait();
-        if (r < 0) {
-          lderr(cct) << "failed to enable mirroring: " << cpp_strerror(r)
-                     << dendl;
-          goto err_remove_child;
-        }
-      }
-    }
+    ThreadPool *thread_pool;
+    ContextWQ *op_work_queue;
+    ImageCtx::get_thread_pool_instance(cct, &thread_pool, &op_work_queue);
 
-    ldout(cct, 2) << "done." << dendl;
-    r = c_imctx->state->close();
-    return r;
+    C_SaferCond cond;
+    auto *req = image::CloneRequest<>::create(
+      p_imctx, c_ioctx, std::string(c_name), c_opts, non_primary_global_image_id,
+      primary_mirror_uuid, op_work_queue, &cond);
+    req->send();
 
-  err_remove_child:
-    partial_r = cls_client::remove_child(&c_ioctx, RBD_CHILDREN, pspec,
-                                         c_imctx->id);
-    if (partial_r < 0) {
-     lderr(cct) << "Error removing failed clone from list of children: "
-                << cpp_strerror(partial_r) << dendl;
-    }
-  err_close_child:
-    c_imctx->state->close();
-  err_remove:
-    partial_r = remove(c_ioctx, c_name, "", no_op);
-    if (partial_r < 0) {
-      lderr(cct) << "Error removing failed clone: "
-                << cpp_strerror(partial_r) << dendl;
-    }
-    return r;
+    return cond.wait();
   }
 
   int rename(IoCtx& io_ctx, const char *srcname, const char *dstname)