]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cls/rbd: add functions to get group snap orders 58002/head
authorN Balachandran <nibalach@redhat.com>
Mon, 22 Jul 2024 06:22:37 +0000 (11:52 +0530)
committerN Balachandran <nibalach@redhat.com>
Tue, 6 Aug 2024 04:04:46 +0000 (09:34 +0530)
Added functions to get the group snap order keys.

Signed-off-by: N Balachandran <nibalach@redhat.com>
src/cls/rbd/cls_rbd.cc
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/test/cls_rbd/test_cls_rbd.cc

index affb986aeffc499465c8c50e0315bcc9a6530a8e..b84630e14860bc761b4cc2329eddc04c28a7f1f3 100644 (file)
@@ -7484,7 +7484,6 @@ int group_snap_set(cls_method_context_t hctx,
     }
 
     uint64_t max_order = 0;
-
     r = read_key(hctx, group::RBD_GROUP_SNAP_MAX_ORDER_KEY, &max_order);
     if (r < 0 && r != -ENOENT) {
       return r;
@@ -7499,6 +7498,7 @@ int group_snap_set(cls_method_context_t hctx,
               cpp_strerror(r).c_str());
       return r;
     }
+
     r = cls_cxx_map_set_val(hctx, order_key, &bl);
     if (r < 0) {
       CLS_ERR("error setting key: %s : %s", order_key.c_str(),
@@ -7640,6 +7640,60 @@ int group_snap_list(cls_method_context_t hctx,
   return 0;
 }
 
+int group_snap_list_order(cls_method_context_t hctx,
+                          bufferlist *in, bufferlist *out)
+{
+  CLS_LOG(20, "group_snap_list_order");
+
+  std::string start_after;
+  uint64_t max_return;
+  try {
+    auto iter = in->cbegin();
+    decode(start_after, iter);
+    decode(max_return, iter);
+  } catch (const ceph::buffer::error &err) {
+    return -EINVAL;
+  }
+
+  std::map<std::string, uint64_t> group_snaps_order;
+  int max_read = RBD_MAX_KEYS_READ;
+  bool more;
+  std::string last_read = group::snap_order_key(start_after);
+  std::map<std::string, bufferlist> vals;
+
+  do {
+    int r = cls_cxx_map_get_vals(hctx, last_read,
+                                 group::RBD_GROUP_SNAP_ORDER_KEY_PREFIX,
+                                 max_read, &vals, &more);
+    if (r < 0) {
+      CLS_ERR("error getting snapshot orders: %s", cpp_strerror(r).c_str());
+      return r;
+    }
+
+    for (auto it = vals.begin();
+         it != vals.end() && group_snaps_order.size() < max_return; ++it) {
+      std::string snap_id = group::snap_id_from_order_key(it->first);
+      auto iter = it->second.cbegin();
+      uint64_t order;
+      try {
+        decode(order, iter);
+      } catch (const ceph::buffer::error &err) {
+        CLS_ERR("error decoding snapshot order: %s", snap_id.c_str());
+        return -EIO;
+      }
+      group_snaps_order[snap_id] = order;
+    }
+    if (!vals.empty()) {
+      last_read = vals.rbegin()->first;
+    } else {
+      ceph_assert(!more);
+    }
+  } while (more && (group_snaps_order.size() < max_return));
+
+  encode(group_snaps_order, *out);
+  return 0;
+}
+
 namespace trash {
 
 static const std::string IMAGE_KEY_PREFIX("id_");
@@ -8266,6 +8320,7 @@ CLS_INIT(rbd)
   cls_method_handle_t h_group_snap_remove;
   cls_method_handle_t h_group_snap_get_by_id;
   cls_method_handle_t h_group_snap_list;
+  cls_method_handle_t h_group_snap_list_order;
   cls_method_handle_t h_trash_add;
   cls_method_handle_t h_trash_remove;
   cls_method_handle_t h_trash_list;
@@ -8649,6 +8704,9 @@ CLS_INIT(rbd)
   cls_register_cxx_method(h_class, "group_snap_list",
                          CLS_METHOD_RD,
                          group_snap_list, &h_group_snap_list);
+  cls_register_cxx_method(h_class, "group_snap_list_order",
+                         CLS_METHOD_RD,
+                         group_snap_list_order, &h_group_snap_list_order);
 
   /* rbd_trash object methods */
   cls_register_cxx_method(h_class, "trash_add",
index 2f1f37eaa9f72ab0f3b34f1e3dfa835df29b516f..ad480c47d5c44613d5f05236079573b9809bd5ac 100644 (file)
@@ -2782,6 +2782,30 @@ int group_snap_list(librados::IoCtx *ioctx, const std::string &oid,
   return 0;
 }
 
+int group_snap_list_order(librados::IoCtx *ioctx, const std::string &oid,
+                          const std::string &start, uint64_t max_return,
+                          std::map<std::string, uint64_t> *snap_order)
+{
+  using ceph::encode;
+  using ceph::decode;
+  bufferlist inbl, outbl;
+  encode(start, inbl);
+  encode(max_return, inbl);
+
+  int r = ioctx->exec(oid, "rbd", "group_snap_list_order", inbl, outbl);
+  if (r < 0) {
+    return r;
+  }
+  auto iter = outbl.cbegin();
+  try {
+    decode(*snap_order, iter);
+  } catch (const ceph::buffer::error &err) {
+    return -EBADMSG;
+  }
+
+  return 0;
+}
+
 // rbd_trash functions
 void trash_add(librados::ObjectWriteOperation *op,
                const std::string &id,
index 38098805e98c487ada77ab21b0a3d7adf9a7e395..4005c51836c73a039ad3fd57882ea6867f337265 100644 (file)
@@ -584,7 +584,10 @@ int group_snap_list(librados::IoCtx *ioctx, const std::string &oid,
                     const cls::rbd::GroupSnapshot &start,
                     uint64_t max_return,
                     std::vector<cls::rbd::GroupSnapshot> *snapshots);
-
+int group_snap_list_order(librados::IoCtx *ioctx, const std::string &oid,
+                          const std::string &snap_id, uint64_t max_return,
+                          std::map<std::string, uint64_t> *snap_order);
 // operations on rbd_trash object
 void trash_add(librados::ObjectWriteOperation *op,
                const std::string &id,
index 3e46997750f7027585e3b829937211eec19abc36..9093b5355d5114e21da70114e5cd8a51fa154998 100644 (file)
@@ -2692,18 +2692,56 @@ TEST_F(TestClsRbd, group_snap_list) {
   ASSERT_EQ(0, ioctx.create(group_id, true));
 
   string snap_id1 = "snap_id1";
-  cls::rbd::GroupSnapshot snap1 = {snap_id1, "test_snapshot1", cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
+  cls::rbd::GroupSnapshot snap1 = {snap_id1, "test_snapshot1",
+                                  cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
   ASSERT_EQ(0, group_snap_set(&ioctx, group_id, snap1));
 
+  string snap_id0 = "snap_id0";
+  cls::rbd::GroupSnapshot snap0 = {snap_id0, "test_snapshot0",
+                                  cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
+  ASSERT_EQ(0, group_snap_set(&ioctx, group_id, snap0));
+
   string snap_id2 = "snap_id2";
-  cls::rbd::GroupSnapshot snap2 = {snap_id2, "test_snapshot2", cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
+  cls::rbd::GroupSnapshot snap2 = {snap_id2, "test_snapshot2",
+                                  cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
   ASSERT_EQ(0, group_snap_set(&ioctx, group_id, snap2));
 
   std::vector<cls::rbd::GroupSnapshot> snapshots;
-  ASSERT_EQ(0, group_snap_list(&ioctx, group_id, cls::rbd::GroupSnapshot(), 10, &snapshots));
-  ASSERT_EQ(2U, snapshots.size());
-  ASSERT_EQ(snap_id1, snapshots[0].id);
-  ASSERT_EQ(snap_id2, snapshots[1].id);
+  ASSERT_EQ(0, group_snap_list(&ioctx, group_id, cls::rbd::GroupSnapshot(),
+                               10, &snapshots));
+  ASSERT_EQ(3U, snapshots.size());
+
+  ASSERT_EQ(snap_id0, snapshots[0].id);
+  ASSERT_EQ(snap_id1, snapshots[1].id);
+  ASSERT_EQ(snap_id2, snapshots[2].id);
+
+  std::map<std::string, uint64_t> snap_orders;
+  ASSERT_EQ(0, group_snap_list_order(&ioctx, group_id, "", 10, &snap_orders));
+  ASSERT_EQ(3U, snap_orders.size());
+
+  ASSERT_EQ(1, snap_orders[snap_id1]);
+  ASSERT_EQ(2, snap_orders[snap_id0]);
+  ASSERT_EQ(3, snap_orders[snap_id2]);
+
+  ASSERT_EQ(0, group_snap_remove(&ioctx, group_id, snap_id2));
+
+  ASSERT_EQ(0, group_snap_list_order(&ioctx, group_id, "", 10, &snap_orders));
+  ASSERT_EQ(2U, snap_orders.size());
+
+  ASSERT_EQ(1, snap_orders[snap_id1]);
+  ASSERT_EQ(2, snap_orders[snap_id0]);
+
+  string snap_id4 = "snap_id4";
+  cls::rbd::GroupSnapshot snap4 = {snap_id4, "test_snapshot4",
+                                  cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
+  ASSERT_EQ(0, group_snap_set(&ioctx, group_id, snap4));
+
+  ASSERT_EQ(0, group_snap_list_order(&ioctx, group_id, "", 10, &snap_orders));
+  ASSERT_EQ(3U, snap_orders.size());
+
+  ASSERT_EQ(1, snap_orders[snap_id1]);
+  ASSERT_EQ(2, snap_orders[snap_id0]);
+  ASSERT_EQ(4, snap_orders[snap_id4]);
 }
 
 static std::string hexify(int v) {