]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: allow to add image to group on creation
authorMykola Golub <mgolub@suse.com>
Wed, 27 Jan 2021 17:23:52 +0000 (17:23 +0000)
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Thu, 24 Apr 2025 15:56:22 +0000 (21:26 +0530)
Signed-off-by: Mykola Golub <mgolub@suse.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
src/include/rbd/librbd.h
src/librbd/image/CreateRequest.cc
src/librbd/image/CreateRequest.h
src/librbd/internal.cc

index f68e1c654b84cb7c32402189aeb3281085799dcf..1fbdc132e947824e4a5cd8de6999a03e5dffd086 100644 (file)
@@ -373,6 +373,8 @@ enum {
   RBD_IMAGE_OPTION_FLATTEN = 11,
   RBD_IMAGE_OPTION_CLONE_FORMAT = 12,
   RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE = 13,
+  RBD_IMAGE_OPTION_GROUP_NAME = 14,
+  RBD_IMAGE_OPTION_GROUP_POOL = 15,
 };
 
 typedef enum {
index 71fb9cf26d052f9c297bb13b79b6fa764dd4c0f6..03c2572975e668c922cb81e3994a950fef9d407d 100644 (file)
@@ -13,6 +13,8 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/asio/ContextWQ.h"
+#include "librbd/group/AddImageRequest.h"
+#include "librbd/group/RemoveImageRequest.h"
 #include "librbd/image/Types.h"
 #include "librbd/image/ValidatePoolRequest.h"
 #include "librbd/journal/CreateRequest.h"
@@ -214,6 +216,9 @@ CreateRequest<I>::CreateRequest(const ConfigProxy& config, IoCtx &ioctx,
     m_features |= RBD_FEATURE_STRIPINGV2;
   }
 
+  image_options.get(RBD_IMAGE_OPTION_GROUP_NAME, &m_group_name);
+  image_options.get(RBD_IMAGE_OPTION_GROUP_POOL, &m_group_pool);
+
   ldout(m_cct, 10) << "name=" << m_image_name << ", "
                    << "id=" << m_image_id << ", "
                    << "size=" << m_size << ", "
@@ -225,7 +230,8 @@ CreateRequest<I>::CreateRequest(const ConfigProxy& config, IoCtx &ioctx,
                    << "journal_splay_width="
                    << (uint64_t)m_journal_splay_width << ", "
                    << "journal_pool=" << m_journal_pool << ", "
-                   << "data_pool=" << m_data_pool << dendl;
+                   << "data_pool=" << m_data_pool << ", "
+                   << "group=" << m_group_pool << "/" << m_group_name << dendl;
 }
 
 template<typename I>
@@ -275,7 +281,7 @@ void CreateRequest<I>::validate_data_pool() {
   }
 
   if (!m_config.get_val<bool>("rbd_validate_pool")) {
-    add_image_to_directory();
+    validate_group();
     return;
   }
 
@@ -301,6 +307,69 @@ void CreateRequest<I>::handle_validate_data_pool(int r) {
     return;
   }
 
+  validate_group();
+}
+
+template <typename I>
+void CreateRequest<I>::validate_group() {
+  if (m_group_name.empty()) {
+    add_image_to_directory();
+    return;
+  }
+
+  ldout(m_cct, 15) << dendl;
+
+  if (m_group_pool.empty() || m_group_pool == m_io_ctx.get_pool_name()) {
+    m_group_io_ctx = m_io_ctx;
+  } else {
+    int64_t pool_id = librados::Rados(m_io_ctx).pool_lookup(
+        m_group_pool.c_str());
+    if (pool_id < 0) {
+      lderr(m_cct) << "group pool " << m_group_pool << " does not exist" << dendl;
+      complete(-EINVAL);
+      return;
+    }
+    int r = util::create_ioctx(m_io_ctx, "group pool", pool_id, {},
+                               &m_group_io_ctx);
+    if (r < 0) {
+      lderr(m_cct) << "failed to open group pool " << m_group_pool << ": "
+                   << cpp_strerror(r) << dendl;
+      complete(r);
+      return;
+    }
+  }
+
+  librados::ObjectReadOperation op;
+  cls_client::dir_get_id_start(&op, m_group_name);
+
+  auto comp = create_rados_callback<
+      CreateRequest<I>, &CreateRequest<I>::handle_validate_group>(this);
+
+  m_outbl.clear();
+  int r = m_group_io_ctx.aio_operate(RBD_GROUP_DIRECTORY, comp, &op, &m_outbl);
+  ceph_assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void CreateRequest<I>::handle_validate_group(int r) {
+  ldout(m_cct, 15) << "r=" << r << dendl;
+
+  if (r >= 0) {
+    auto it = m_outbl.cbegin();
+    r = cls_client::dir_get_id_finish(&it, &m_group_id);
+  }
+
+  if (r == -ENOENT) {
+    lderr(m_cct) << "group " << m_group_name << " does not exist" << dendl;
+    complete(r);
+    return;
+  } else if (r < 0) {
+    lderr(m_cct) << "failed to validate group: " << cpp_strerror(r) << dendl;
+    complete(r);
+    return;
+  }
+
   add_image_to_directory();
 }
 
@@ -514,7 +583,7 @@ void CreateRequest<I>::handle_set_stripe_unit_count(int r) {
 template<typename I>
 void CreateRequest<I>::object_map_resize() {
   if ((m_features & RBD_FEATURE_OBJECT_MAP) == 0) {
-    fetch_mirror_mode();
+    add_image_to_group();
     return;
   }
 
@@ -545,9 +614,40 @@ void CreateRequest<I>::handle_object_map_resize(int r) {
     return;
   }
 
-  fetch_mirror_mode();
+  add_image_to_group();
 }
 
+template<typename I>
+void CreateRequest<I>::add_image_to_group() {
+  if (m_group_id.empty()) {
+    fetch_mirror_mode();
+    return;
+  }
+
+  ldout(m_cct, 15) << dendl;
+
+  auto ctx = create_context_callback<
+    CreateRequest<I>, &CreateRequest<I>::handle_add_image_to_group>(this);
+  auto req = group::AddImageRequest<I>::create(m_group_io_ctx, m_group_id,
+                                               m_io_ctx, m_image_id, ctx);
+  req->send();
+}
+
+template<typename I>
+void CreateRequest<I>::handle_add_image_to_group(int r) {
+  ldout(m_cct, 15) << "r=" << r << dendl;
+
+   if (r < 0) {
+     lderr(m_cct) << "error adding image to group: " << cpp_strerror(r)
+                  << dendl;
+     m_r_saved = r;
+     remove_object_map();
+     return;
+   }
+
+   fetch_mirror_mode();
+ }
+
 template<typename I>
 void CreateRequest<I>::fetch_mirror_mode() {
   if ((m_features & RBD_FEATURE_JOURNALING) == 0) {
@@ -578,7 +678,7 @@ void CreateRequest<I>::handle_fetch_mirror_mode(int r) {
                  << dendl;
 
     m_r_saved = r;
-    remove_object_map();
+    remove_image_from_group();
     return;
   }
 
@@ -590,7 +690,7 @@ void CreateRequest<I>::handle_fetch_mirror_mode(int r) {
       lderr(m_cct) << "Failed to retrieve mirror mode" << dendl;
 
       m_r_saved = r;
-      remove_object_map();
+      remove_image_from_group();
       return;
     }
   }
@@ -635,7 +735,7 @@ void CreateRequest<I>::handle_journal_create(int r) {
                  << dendl;
 
     m_r_saved = r;
-    remove_object_map();
+    remove_image_from_group();
     return;
   }
 
@@ -693,7 +793,7 @@ void CreateRequest<I>::complete(int r) {
 template<typename I>
 void CreateRequest<I>::journal_remove() {
   if ((m_features & RBD_FEATURE_JOURNALING) == 0) {
-    remove_object_map();
+    remove_image_from_group();
     return;
   }
 
@@ -722,6 +822,35 @@ void CreateRequest<I>::handle_journal_remove(int r) {
                  << cpp_strerror(r) << dendl;
   }
 
+  remove_image_from_group();
+}
+
+template<typename I>
+void CreateRequest<I>::remove_image_from_group() {
+  if (m_group_id.empty()) {
+    remove_object_map();
+    return;
+  }
+
+  ldout(m_cct, 15) << dendl;
+
+  auto ctx = create_context_callback<
+    CreateRequest<I>, &CreateRequest<I>::handle_remove_image_from_group>(this);
+
+  auto req = group::RemoveImageRequest<I>::create(m_group_io_ctx, m_group_id,
+                                                  m_io_ctx, m_image_id, ctx);
+  req->send();
+}
+
+template<typename I>
+void CreateRequest<I>::handle_remove_image_from_group(int r) {
+  ldout(m_cct, 15) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(m_cct) << "error cleaning up group after creation failed: "
+                 << cpp_strerror(r) << dendl;
+  }
+
   remove_object_map();
 }
 
index 9cb0eec7c8d2d86a3aa6a6e1f4480e18d4d355ed..b904cbe5432598aa9aa5f86f4b79c564b15b6532 100644 (file)
@@ -57,7 +57,10 @@ private:
    *                               VALIDATE DATA POOL           v (pool validation
    *                                     |                      .  disabled)
    *                                     v                      .
-   * (error: bottom up)         ADD IMAGE TO DIRECTORY  < . . . .
+   *                               VALIDATE GROUP < . . . . . . .
+   *                                     |
+   *                                     v
+   * (error: bottom up)         ADD IMAGE TO DIRECTORY
    *  _______<_______                    |
    * |               |                   v
    * |               |            CREATE ID OBJECT
@@ -74,18 +77,21 @@ private:
    * |      REMOVE HEADER OBJ<------/    v                     /. (object-map
    * |               |\           OBJECT MAP RESIZE . . < . . * v  disabled)
    * |               | \              /  |  \ . . . . . > . . . .
-   * |               |  *<-----------/   v                     /. (journaling
+   * |               |  *<-----------/   v                     /. (group not
+   * |               |\          ADD IMAGE TO GROUP . . < . . * v  specified)
+   * |               | \              /  |  \ . . . . . > . . . .
+   * |      REMOVE OBJECT MAP<-------/   v                      . (journaling
    * |               |             FETCH MIRROR MODE. . < . . * v  disabled)
-   * |               |                /   |                     .
-   * |     REMOVE OBJECT MAP<--------/    v                     .
+   * |               |                /                       .
+   * |      REMOVE FROM GROUP <------/   v                      .
    * |               |\             JOURNAL CREATE              .
-   * |               | \               /  |                     .
-   * v               |  *<------------/   v                     .
-   * |               |           MIRROR IMAGE ENABLE            .
-   * |               |                /   |                     .
-   * |        JOURNAL REMOVE*<-------/    |                     .
-   * |                                    v                     .
-   * |_____________>___________________<finish> . . . . < . . . .
+   * |               | \              /  |                      .
+   * v               |  *<-----------/   v                      .
+   * |               |          MIRROR IMAGE ENABLE             .
+   * |               |               /   |                      .
+   * |        JOURNAL REMOVE*<------/    |                      .
+   * |                                                        .
+   * |_____________>__________________<finish>. . . . . < . . . .
    *
    * @endverbatim
    */
@@ -115,6 +121,10 @@ private:
   std::string m_journal_pool;
   std::string m_data_pool;
   int64_t m_data_pool_id = -1;
+  std::string m_group_name;
+  std::string m_group_id;
+  std::string m_group_pool;
+  IoCtx m_group_io_ctx;
   uint32_t m_create_flags;
   cls::rbd::MirrorImageMode m_mirror_image_mode;
   const std::string m_non_primary_global_image_id;
@@ -136,6 +146,9 @@ private:
   void validate_data_pool();
   void handle_validate_data_pool(int r);
 
+  void validate_group();
+  void handle_validate_group(int r);
+
   void add_image_to_directory();
   void handle_add_image_to_directory(int r);
 
@@ -154,6 +167,9 @@ private:
   void object_map_resize();
   void handle_object_map_resize(int r);
 
+  void add_image_to_group();
+  void handle_add_image_to_group(int r);
+
   void fetch_mirror_mode();
   void handle_fetch_mirror_mode(int r);
 
@@ -169,6 +185,9 @@ private:
   void journal_remove();
   void handle_journal_remove(int r);
 
+  void remove_image_from_group();
+  void handle_remove_image_from_group(int r);
+
   void remove_object_map();
   void handle_remove_object_map(int r);
 
index 5676631723291c73ebb917f27946c29bb7197669..6f152f6ffb648201c8123c20b2e2595d792bce17 100644 (file)
@@ -299,6 +299,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     {RBD_IMAGE_OPTION_FLATTEN, UINT64},
     {RBD_IMAGE_OPTION_CLONE_FORMAT, UINT64},
     {RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE, UINT64},
+    {RBD_IMAGE_OPTION_GROUP_NAME, STR},
+    {RBD_IMAGE_OPTION_GROUP_POOL, STR},
   };
 
   std::string image_option_name(int optname) {
@@ -331,6 +333,10 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
       return "clone_format";
     case RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE:
       return "mirror_image_mode";
+    case RBD_IMAGE_OPTION_GROUP_NAME:
+      return "group_name";
+    case RBD_IMAGE_OPTION_GROUP_POOL:
+      return "group_pool";
     default:
       return "unknown (" + stringify(optname) + ")";
     }