]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: introduce 'group add/remove image' async requests
authorMykola Golub <mgolub@suse.com>
Wed, 27 Jan 2021 17:19:32 +0000 (17:19 +0000)
committerIlya Dryomov <idryomov@gmail.com>
Sun, 28 Sep 2025 18:24:58 +0000 (20:24 +0200)
Signed-off-by: Mykola Golub <mgolub@suse.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
src/librbd/CMakeLists.txt
src/librbd/group/AddImageRequest.cc [new file with mode: 0644]
src/librbd/group/AddImageRequest.h [new file with mode: 0644]
src/librbd/group/RemoveImageRequest.cc [new file with mode: 0644]
src/librbd/group/RemoveImageRequest.h [new file with mode: 0644]

index 7c7d1c9bf1b7b84b9b4be385f8c07d19b2709d3e..b787b72bd42633503bb8b68126198841865965e4 100644 (file)
@@ -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 (file)
index 0000000..7ab9efc
--- /dev/null
@@ -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 <typename I>
+void AddImageRequest<I>::send() {
+  pre_link();
+}
+
+template <typename I>
+void AddImageRequest<I>::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<I>, &AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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<I>, &AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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<I>, &AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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 <typename I>
+void AddImageRequest<I>::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<librbd::ImageCtx>;
diff --git a/src/librbd/group/AddImageRequest.h b/src/librbd/group/AddImageRequest.h
new file mode 100644 (file)
index 0000000..f8a0195
--- /dev/null
@@ -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 <string>
+
+class Context;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace group {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+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
+   *
+   * <start>
+   *    |
+   *    v
+   *  PRE_LINK
+   *    |
+   *    v
+   *  ADD_GROUP
+   *    |
+   *    v
+   *  POST_LINK
+   *    |
+   *    v
+   *  <finish>
+   *
+   * @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<librbd::ImageCtx>;
+
+#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 (file)
index 0000000..d0ec081
--- /dev/null
@@ -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 <typename I>
+void RemoveImageRequest<I>::send() {
+  pre_unlink();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::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<I>, &RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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<I>, &RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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<I>, &RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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 <typename I>
+void RemoveImageRequest<I>::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<librbd::ImageCtx>;
diff --git a/src/librbd/group/RemoveImageRequest.h b/src/librbd/group/RemoveImageRequest.h
new file mode 100644 (file)
index 0000000..2f01089
--- /dev/null
@@ -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 <string>
+
+class Context;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace group {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+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
+   *
+   * <start>
+   *    |
+   *    v
+   *  PRE_UNLINK
+   *    |
+   *    v
+   *  REMOVE_GROUP
+   *    |
+   *    v
+   *  POST_UNLINK
+   *    |
+   *    v
+   *  <finish>
+   *
+   * @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<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H