From bc45e9a77cf9e658c7606de15f9c101c7964a6d2 Mon Sep 17 00:00:00 2001 From: N Balachandran Date: Mon, 22 Jul 2024 11:52:37 +0530 Subject: [PATCH] cls/rbd: add functions to get group snap orders Added functions to get the group snap order keys. Signed-off-by: N Balachandran --- src/cls/rbd/cls_rbd.cc | 60 +++++++++++++++++++++++++++++++- src/cls/rbd/cls_rbd_client.cc | 24 +++++++++++++ src/cls/rbd/cls_rbd_client.h | 5 ++- src/test/cls_rbd/test_cls_rbd.cc | 50 ++++++++++++++++++++++---- 4 files changed, 131 insertions(+), 8 deletions(-) diff --git a/src/cls/rbd/cls_rbd.cc b/src/cls/rbd/cls_rbd.cc index affb986aeffc4..b84630e14860b 100644 --- a/src/cls/rbd/cls_rbd.cc +++ b/src/cls/rbd/cls_rbd.cc @@ -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 group_snaps_order; + int max_read = RBD_MAX_KEYS_READ; + bool more; + std::string last_read = group::snap_order_key(start_after); + std::map 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", diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc index 2f1f37eaa9f72..ad480c47d5c44 100644 --- a/src/cls/rbd/cls_rbd_client.cc +++ b/src/cls/rbd/cls_rbd_client.cc @@ -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 *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, diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h index 38098805e98c4..4005c51836c73 100644 --- a/src/cls/rbd/cls_rbd_client.h +++ b/src/cls/rbd/cls_rbd_client.h @@ -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 *snapshots); - +int group_snap_list_order(librados::IoCtx *ioctx, const std::string &oid, + const std::string &snap_id, uint64_t max_return, + std::map *snap_order); + // operations on rbd_trash object void trash_add(librados::ObjectWriteOperation *op, const std::string &id, diff --git a/src/test/cls_rbd/test_cls_rbd.cc b/src/test/cls_rbd/test_cls_rbd.cc index 3e46997750f70..9093b5355d511 100644 --- a/src/test/cls_rbd/test_cls_rbd.cc +++ b/src/test/cls_rbd/test_cls_rbd.cc @@ -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 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 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) { -- 2.39.5