Added functions to get the group snap order keys.
Signed-off-by: N Balachandran <nibalach@redhat.com>
}
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;
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(),
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_");
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;
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",
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,
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,
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) {