From f117dc1259ee257f04eeaaa176b1a251b5ae5f1d Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Wed, 27 Jan 2021 17:19:32 +0000 Subject: [PATCH] librbd: introduce 'group add/remove image' async requests Signed-off-by: Mykola Golub Signed-off-by: Prasanna Kumar Kalever --- src/librbd/CMakeLists.txt | 2 + src/librbd/group/AddImageRequest.cc | 138 +++++++++++++++++++++++++ src/librbd/group/AddImageRequest.h | 90 ++++++++++++++++ src/librbd/group/RemoveImageRequest.cc | 131 +++++++++++++++++++++++ src/librbd/group/RemoveImageRequest.h | 88 ++++++++++++++++ 5 files changed, 449 insertions(+) create mode 100644 src/librbd/group/AddImageRequest.cc create mode 100644 src/librbd/group/AddImageRequest.h create mode 100644 src/librbd/group/RemoveImageRequest.cc create mode 100644 src/librbd/group/RemoveImageRequest.h diff --git a/src/librbd/CMakeLists.txt b/src/librbd/CMakeLists.txt index 7c7d1c9bf1b..b787b72bd42 100644 --- a/src/librbd/CMakeLists.txt +++ b/src/librbd/CMakeLists.txt @@ -78,6 +78,8 @@ set(librbd_internal_srcs exclusive_lock/PreReleaseRequest.cc exclusive_lock/StandardPolicy.cc group/ListSnapshotsRequest.cc + group/AddImageRequest.cc + group/RemoveImageRequest.cc image/AttachChildRequest.cc image/AttachParentRequest.cc image/CloneRequest.cc diff --git a/src/librbd/group/AddImageRequest.cc b/src/librbd/group/AddImageRequest.cc new file mode 100644 index 00000000000..7ab9efcabfd --- /dev/null +++ b/src/librbd/group/AddImageRequest.cc @@ -0,0 +1,138 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/group/AddImageRequest.h" +#include "include/ceph_assert.h" +#include "common/dout.h" +#include "common/errno.h" +#include "common/ceph_context.h" +#include "cls/rbd/cls_rbd_client.h" +#include "librbd/Utils.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::group::AddImageRequest: " << this \ + << " " << __func__ << ": " + +namespace librbd { +namespace group { + +using util::create_rados_callback; + +template +void AddImageRequest::send() { + pre_link(); +} + +template +void AddImageRequest::pre_link() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + cls_client::group_image_set( + &op, {m_image_id, m_image_io_ctx.get_id(), + cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE}); + auto comp = create_rados_callback< + AddImageRequest, &AddImageRequest::handle_pre_link>(this); + + int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp, + &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void AddImageRequest::handle_pre_link(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to pre link group image: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + add_group(); +} + +template +void AddImageRequest::add_group() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + cls_client::image_group_add(&op, {m_group_id, m_group_io_ctx.get_id()}); + auto comp = create_rados_callback< + AddImageRequest, &AddImageRequest::handle_add_group>(this); + + int r = m_image_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void AddImageRequest::handle_add_group(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to add image group: " << cpp_strerror(r) << dendl; + m_ret_val = r; + } + + post_link(); +} + +template +void AddImageRequest::post_link() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + + if (m_ret_val < 0) { + cls_client::group_image_remove(&op, {m_image_id, m_image_io_ctx.get_id()}); + } else { + cls_client::group_image_set( + &op, {m_image_id, m_image_io_ctx.get_id(), + cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED}); + } + auto comp = create_rados_callback< + AddImageRequest, &AddImageRequest::handle_post_link>(this); + + int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp, + &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void AddImageRequest::handle_post_link(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to post link group image: " << cpp_strerror(r) + << dendl; + if (m_ret_val == 0) { + m_ret_val = r; + } + } + + finish(m_ret_val); +} + +template +void AddImageRequest::finish(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + m_on_finish->complete(r); +} + +} // namespace group +} // namespace librbd + +template class librbd::group::AddImageRequest; diff --git a/src/librbd/group/AddImageRequest.h b/src/librbd/group/AddImageRequest.h new file mode 100644 index 00000000000..f8a01952dbc --- /dev/null +++ b/src/librbd/group/AddImageRequest.h @@ -0,0 +1,90 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H +#define CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H + +#include "include/int_types.h" +#include "include/types.h" +#include "include/rados/librados.hpp" +#include + +class Context; + +namespace librbd { + +struct ImageCtx; + +namespace group { + +template +class AddImageRequest { +public: + static AddImageRequest *create(librados::IoCtx &group_io_ctx, + const std::string &group_id, + librados::IoCtx &image_io_ctx, + const std::string &image_id, + Context *on_finish) { + return new AddImageRequest(group_io_ctx, group_id, image_io_ctx, image_id, + on_finish); + } + + AddImageRequest(librados::IoCtx &group_io_ctx, + const std::string &group_id, + librados::IoCtx &image_io_ctx, + const std::string &image_id, + Context *on_finish) + : m_group_io_ctx(group_io_ctx), m_group_id(group_id), + m_image_io_ctx(image_io_ctx), m_image_id(image_id), + m_on_finish(on_finish) { + } + + void send(); + +private: + /** + * @verbatim + * + * + * | + * v + * PRE_LINK + * | + * v + * ADD_GROUP + * | + * v + * POST_LINK + * | + * v + * + * + * @endverbatim + */ + + librados::IoCtx &m_group_io_ctx; + const std::string m_group_id; + librados::IoCtx &m_image_io_ctx; + const std::string m_image_id; + Context *m_on_finish; + + int m_ret_val = 0; + + void pre_link(); + void handle_pre_link(int r); + + void add_group(); + void handle_add_group(int r); + + void post_link(); + void handle_post_link(int r); + + void finish(int r); +}; + +} // namespace group +} // namespace librbd + +extern template class librbd::group::AddImageRequest; + +#endif // CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H diff --git a/src/librbd/group/RemoveImageRequest.cc b/src/librbd/group/RemoveImageRequest.cc new file mode 100644 index 00000000000..d0ec081b59d --- /dev/null +++ b/src/librbd/group/RemoveImageRequest.cc @@ -0,0 +1,131 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/group/RemoveImageRequest.h" +#include "include/ceph_assert.h" +#include "common/dout.h" +#include "common/errno.h" +#include "common/ceph_context.h" +#include "cls/rbd/cls_rbd_client.h" +#include "librbd/Utils.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::group::RemoveImageRequest: " << this \ + << " " << __func__ << ": " + +namespace librbd { +namespace group { + +using librbd::util::create_rados_callback; + +template +void RemoveImageRequest::send() { + pre_unlink(); +} + +template +void RemoveImageRequest::pre_unlink() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + cls_client::group_image_set( + &op, {m_image_id, m_image_io_ctx.get_id(), + cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE}); + auto comp = create_rados_callback< + RemoveImageRequest, &RemoveImageRequest::handle_pre_unlink>(this); + + int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp, + &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void RemoveImageRequest::handle_pre_unlink(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to pre unlink group image: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + remove_group(); +} + +template +void RemoveImageRequest::remove_group() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + cls_client::image_group_remove(&op, {m_group_id, m_group_io_ctx.get_id()}); + auto comp = create_rados_callback< + RemoveImageRequest, &RemoveImageRequest::handle_remove_group>(this); + + int r = m_image_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void RemoveImageRequest::handle_remove_group(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to remove image group: " << cpp_strerror(r) << dendl; + finish(r); + return; + } + + post_unlink(); +} + +template +void RemoveImageRequest::post_unlink() { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << dendl; + + librados::ObjectWriteOperation op; + cls_client::group_image_remove(&op, {m_image_id, m_image_io_ctx.get_id()}); + auto comp = create_rados_callback< + RemoveImageRequest, &RemoveImageRequest::handle_post_unlink>(this); + + int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp, + &op); + ceph_assert(r == 0); + comp->release(); +} + +template +void RemoveImageRequest::handle_post_unlink(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to post unlink group image: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + finish(0); +} + +template +void RemoveImageRequest::finish(int r) { + CephContext *cct = (CephContext *)m_image_io_ctx.cct(); + ldout(cct, 10) << "r=" << r << dendl; + + m_on_finish->complete(r); +} + +} // namespace group +} // namespace librbd + +template class librbd::group::RemoveImageRequest; diff --git a/src/librbd/group/RemoveImageRequest.h b/src/librbd/group/RemoveImageRequest.h new file mode 100644 index 00000000000..2f01089180e --- /dev/null +++ b/src/librbd/group/RemoveImageRequest.h @@ -0,0 +1,88 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H +#define CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H + +#include "include/int_types.h" +#include "include/types.h" +#include "include/rados/librados.hpp" +#include + +class Context; + +namespace librbd { + +struct ImageCtx; + +namespace group { + +template +class RemoveImageRequest { +public: + static RemoveImageRequest *create(librados::IoCtx &group_io_ctx, + const std::string &group_id, + librados::IoCtx &image_io_ctx, + const std::string &image_id, + Context *on_finish) { + return new RemoveImageRequest(group_io_ctx, group_id, image_io_ctx, + image_id, on_finish); + } + + RemoveImageRequest(librados::IoCtx &group_io_ctx, + const std::string &group_id, + librados::IoCtx &image_io_ctx, + const std::string &image_id, + Context *on_finish) + : m_group_io_ctx(group_io_ctx), m_group_id(group_id), + m_image_io_ctx(image_io_ctx), m_image_id(image_id), + m_on_finish(on_finish) { + } + + void send(); + +private: + /** + * @verbatim + * + * + * | + * v + * PRE_UNLINK + * | + * v + * REMOVE_GROUP + * | + * v + * POST_UNLINK + * | + * v + * + * + * @endverbatim + */ + + librados::IoCtx &m_group_io_ctx; + const std::string m_group_id; + librados::IoCtx &m_image_io_ctx; + const std::string m_image_id; + Context *m_on_finish; + + void pre_unlink(); + void handle_pre_unlink(int r); + + void remove_group(); + void handle_remove_group(int r); + + void post_unlink(); + void handle_post_unlink(int r); + + void finish(int r); +}; + +} // namespace group +} // namespace librbd + +extern template class librbd::group::RemoveImageRequest; + +#endif // CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H -- 2.39.5