X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Flibrbd%2Fimage%2FCloneRequest.cc;fp=src%2Fceph%2Fsrc%2Flibrbd%2Fimage%2FCloneRequest.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=3753b94f85f95f160b681466b919b6686da34f7a;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/librbd/image/CloneRequest.cc b/src/ceph/src/librbd/image/CloneRequest.cc deleted file mode 100644 index 3753b94..0000000 --- a/src/ceph/src/librbd/image/CloneRequest.cc +++ /dev/null @@ -1,568 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "cls/rbd/cls_rbd_client.h" -#include "cls/rbd/cls_rbd_types.h" -#include "common/dout.h" -#include "common/errno.h" -#include "include/assert.h" -#include "librbd/ImageState.h" -#include "librbd/Journal.h" -#include "librbd/image/CloneRequest.h" -#include "librbd/image/CreateRequest.h" -#include "librbd/image/RemoveRequest.h" -#include "librbd/image/RefreshRequest.h" -#include "librbd/mirror/EnableRequest.h" - -#define dout_subsys ceph_subsys_rbd -#undef dout_prefix -#define dout_prefix *_dout << "librbd::image::CloneRequest: " - -namespace librbd { -namespace image { - -using util::create_rados_callback; -using util::create_context_callback; -using util::create_async_context_callback; - -template -CloneRequest::CloneRequest(I *p_imctx, IoCtx &c_ioctx, - const std::string &c_name, - const std::string &c_id, - ImageOptions c_options, - const std::string &non_primary_global_image_id, - const std::string &primary_mirror_uuid, - ContextWQ *op_work_queue, Context *on_finish) - : m_p_imctx(p_imctx), m_ioctx(c_ioctx), m_name(c_name), m_id(c_id), - m_opts(c_options), - m_pspec(m_p_imctx->md_ctx.get_id(), m_p_imctx->id, m_p_imctx->snap_id), - m_non_primary_global_image_id(non_primary_global_image_id), - m_primary_mirror_uuid(primary_mirror_uuid), - m_op_work_queue(op_work_queue), m_on_finish(on_finish), - m_use_p_features(true) { - - m_cct = reinterpret_cast(m_ioctx.cct()); - - bool default_format_set; - m_opts.is_set(RBD_IMAGE_OPTION_FORMAT, &default_format_set); - if (!default_format_set) { - m_opts.set(RBD_IMAGE_OPTION_FORMAT, static_cast(2)); - } - - ldout(m_cct, 20) << "clone " << &m_p_imctx->md_ctx << " name " << m_p_imctx->name - << " snap " << m_p_imctx->snap_name << " to child " << &m_ioctx - << " name " << m_name << " opts = " << &m_opts << dendl; - return; -} - -template -void CloneRequest::send() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - validate_options(); -} - -template -void CloneRequest::validate_options() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - uint64_t format = 0; - m_opts.get(RBD_IMAGE_OPTION_FORMAT, &format); - if (format < 2) { - lderr(m_cct) << "format 2 or later required for clone" << dendl; - return complete(-EINVAL); - } - - if (m_opts.get(RBD_IMAGE_OPTION_FEATURES, &m_features) == 0) { - if (m_features & ~RBD_FEATURES_ALL) { - lderr(m_cct) << "librbd does not support requested features" << dendl; - return complete(-ENOSYS); - } - m_use_p_features = false; - } - - send_validate_parent(); -} - -template -void CloneRequest::send_validate_parent() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - if (m_p_imctx->snap_id == CEPH_NOSNAP) { - lderr(m_cct) << "image to be cloned must be a snapshot" << dendl; - return complete(-EINVAL); - } - - if (m_p_imctx->old_format) { - lderr(m_cct) << "parent image must be in new format" << dendl; - return complete(-EINVAL); - } - - int r = 0; - bool snap_protected; - m_p_imctx->snap_lock.get_read(); - m_p_features = m_p_imctx->features; - m_size = m_p_imctx->get_image_size(m_p_imctx->snap_id); - r = m_p_imctx->is_snap_protected(m_p_imctx->snap_id, &snap_protected); - m_p_imctx->snap_lock.put_read(); - - if ((m_p_features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) { - lderr(m_cct) << "parent image must support layering" << dendl; - return complete(-ENOSYS); - } - - if (r < 0) { - lderr(m_cct) << "unable to locate parent's snapshot" << dendl; - return complete(r); - } - - if (!snap_protected) { - lderr(m_cct) << "parent snapshot must be protected" << dendl; - return complete(-EINVAL); - } - - if ((m_p_features & RBD_FEATURE_JOURNALING) != 0) { - m_force_non_primary = !m_non_primary_global_image_id.empty(); - using klass = CloneRequest; - Context *ctx = create_context_callback< - klass, &klass::handle_validate_parent>(this); - - Journal::is_tag_owner(m_p_imctx, &m_is_primary, ctx); - return; - } - - send_validate_child(); -} - -template -void CloneRequest::handle_validate_parent(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "failed to determine tag ownership: " << cpp_strerror(r) - << dendl; - return complete(r); - } - - if ((m_p_features & RBD_FEATURE_JOURNALING) != 0) { - if (!m_is_primary && !m_force_non_primary) { - lderr(m_cct) << "parent is non-primary mirrored image" << dendl; - return complete(-EINVAL); - } - } - - send_validate_child(); -} - -template -void CloneRequest::send_validate_child() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - using klass = CloneRequest; - librados::AioCompletion *comp = create_rados_callback(this); - - librados::ObjectReadOperation op; - op.stat(NULL, NULL, NULL); - - int r = m_ioctx.aio_operate(util::old_header_name(m_name), comp, &op, &m_out_bl); - assert(r == 0); - comp->release(); -} - -template -void CloneRequest::handle_validate_child(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r != -ENOENT) { - lderr(m_cct) << "rbd image " << m_name << " already exists" << dendl; - return complete(r); - } - - send_create(); -} - -template -void CloneRequest::send_create() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - if (m_use_p_features) { - m_features = m_p_features; - } - - uint64_t order = m_p_imctx->order; - if (m_opts.get(RBD_IMAGE_OPTION_ORDER, &order) != 0) { - m_opts.set(RBD_IMAGE_OPTION_ORDER, order); - } - if ((m_features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) { - lderr(m_cct) << "cloning image must support layering" << dendl; - return complete(-ENOSYS); - } - m_opts.set(RBD_IMAGE_OPTION_FEATURES, m_features); - - using klass = CloneRequest; - Context *ctx = create_context_callback(this); - - RWLock::RLocker snap_locker(m_p_imctx->snap_lock); - CreateRequest *req = CreateRequest::create( - m_ioctx, m_name, m_id, m_size, m_opts, m_non_primary_global_image_id, - m_primary_mirror_uuid, true, m_op_work_queue, ctx); - req->send(); -} - -template -void CloneRequest::handle_create(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "error creating child: " << cpp_strerror(r) << dendl; - return complete(r); - } - send_open(); -} - -template -void CloneRequest::send_open() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - m_imctx = I::create(m_name, "", NULL, m_ioctx, false); - - using klass = CloneRequest; - Context *ctx = create_context_callback(this); - - m_imctx->state->open(true, ctx); -} - -template -void CloneRequest::handle_open(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "Error opening new image: " << cpp_strerror(r) << dendl; - m_r_saved = r; - return send_remove(); - } - - send_set_parent(); -} - -template -void CloneRequest::send_set_parent() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectWriteOperation op; - librbd::cls_client::set_parent(&op, m_pspec, m_size); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - int r = m_imctx->md_ctx.aio_operate(m_imctx->header_oid, - comp, &op); - assert(r == 0); - comp->release(); -} - -template -void CloneRequest::handle_set_parent(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "couldn't set parent: " << cpp_strerror(r) << dendl; - m_r_saved = r; - return send_close(); - } - - send_add_child(); -} - -template -void CloneRequest::send_add_child() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectWriteOperation op; - cls_client::add_child(&op, m_pspec, m_id); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - int r = m_ioctx.aio_operate(RBD_CHILDREN, comp, &op); - assert(r == 0); - comp->release(); -} - -template -void CloneRequest::handle_add_child(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "couldn't add child: " << cpp_strerror(r) << dendl; - m_r_saved = r; - return send_close(); - } - - send_refresh(); -} - -template -void CloneRequest::send_refresh() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - using klass = CloneRequest; - RefreshRequest *req = RefreshRequest::create( - *m_imctx, false, false, - create_context_callback(this)); - req->send(); -} - -template -void CloneRequest::handle_refresh(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - bool snap_protected = false; - if (r == 0) { - m_p_imctx->snap_lock.get_read(); - r = m_p_imctx->is_snap_protected(m_p_imctx->snap_id, &snap_protected); - m_p_imctx->snap_lock.put_read(); - } - - if (r < 0 || !snap_protected) { - m_r_saved = -EINVAL; - return send_close(); - } - - send_metadata_list(); -} - -template -void CloneRequest::send_metadata_list() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::metadata_list_start(&op, "", 0); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - m_out_bl.clear(); - m_p_imctx->md_ctx.aio_operate(m_p_imctx->header_oid, - comp, &op, &m_out_bl); - comp->release(); -} - -template -void CloneRequest::handle_metadata_list(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r == 0) { - bufferlist::iterator it = m_out_bl.begin(); - r = cls_client::metadata_list_finish(&it, &m_pairs); - } - - if (r < 0 && r != -EOPNOTSUPP && r != -EIO) { - lderr(m_cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl; - m_r_saved = r; - send_remove_child(); - } else if (r == 0 && !m_pairs.empty()) { - send_metadata_set(); - } else { - get_mirror_mode(); - } -} - -template -void CloneRequest::send_metadata_set() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectWriteOperation op; - cls_client::metadata_set(&op, m_pairs); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - int r = m_ioctx.aio_operate(m_imctx->header_oid, comp, &op); - assert(r == 0); - comp->release(); -} - -template -void CloneRequest::handle_metadata_set(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl; - m_r_saved = r; - send_remove_child(); - } else { - get_mirror_mode(); - } -} - -template -void CloneRequest::get_mirror_mode() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - if (!m_imctx->test_features(RBD_FEATURE_JOURNALING)) { - send_close(); - return; - } - - librados::ObjectReadOperation op; - cls_client::mirror_mode_get_start(&op); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - m_out_bl.clear(); - m_imctx->md_ctx.aio_operate(RBD_MIRRORING, - comp, &op, &m_out_bl); - comp->release(); -} - -template -void CloneRequest::handle_get_mirror_mode(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r == 0) { - bufferlist::iterator it = m_out_bl.begin(); - r = cls_client::mirror_mode_get_finish(&it, &m_mirror_mode); - } - - if (r < 0 && r != -ENOENT) { - lderr(m_cct) << "failed to retrieve mirror mode: " << cpp_strerror(r) - << dendl; - - m_r_saved = r; - send_remove_child(); - } else { - if (m_mirror_mode == cls::rbd::MIRROR_MODE_POOL || - !m_non_primary_global_image_id.empty()) { - send_enable_mirror(); - } else { - send_close(); - } - } -} - -template -void CloneRequest::send_enable_mirror() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - using klass = CloneRequest; - Context *ctx = create_context_callback(this); - - mirror::EnableRequest *req = mirror::EnableRequest::create( - m_imctx->md_ctx, m_id, m_non_primary_global_image_id, - m_imctx->op_work_queue, ctx); - req->send(); -} - -template -void CloneRequest::handle_enable_mirror(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "failed to enable mirroring: " << cpp_strerror(r) - << dendl; - m_r_saved = r; - send_remove_child(); - } else { - send_close(); - } -} - -template -void CloneRequest::send_close() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - assert(m_imctx != nullptr); - - using klass = CloneRequest; - Context *ctx = create_async_context_callback( - *m_imctx, create_context_callback< - klass, &klass::handle_close>(this)); - m_imctx->state->close(ctx); -} - -template -void CloneRequest::handle_close(int r) { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - m_imctx->destroy(); - m_imctx = nullptr; - - if (r < 0) { - lderr(m_cct) << "couldn't close image: " << cpp_strerror(r) << dendl; - return complete(r); - } - - if (m_r_saved == 0) { - complete(0); - } else { - send_remove(); - } -} - -template -void CloneRequest::send_remove_child() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectWriteOperation op; - cls_client::remove_child(&op, m_pspec, m_id); - - using klass = CloneRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - int r = m_p_imctx->md_ctx.aio_operate(RBD_CHILDREN, comp, &op); - assert(r == 0); - comp->release(); -} - -template -void CloneRequest::handle_remove_child(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "Error removing failed clone from list of children: " - << cpp_strerror(r) << dendl; - } - - send_close(); -} - -template -void CloneRequest::send_remove() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - using klass = CloneRequest; - Context *ctx = create_context_callback(this); - - librbd::image::RemoveRequest<> *req = librbd::image::RemoveRequest<>::create( - m_ioctx, m_name, m_id, false, false, m_no_op, m_op_work_queue, ctx); - req->send(); -} - -template -void CloneRequest::handle_remove(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r < 0) { - lderr(m_cct) << "Error removing failed clone: " - << cpp_strerror(r) << dendl; - } - complete(r); -} - -template -void CloneRequest::complete(int r) { - ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl; - - if (r == 0) { - ldout(m_cct, 20) << "done." << dendl; - } - - m_on_finish->complete(r); - delete this; -} - -} //namespace image -} //namespace librbd - -template class librbd::image::CloneRequest;