cls_method_handle_t h_journal_set_minimum_set;
cls_method_handle_t h_journal_get_active_set;
cls_method_handle_t h_journal_set_active_set;
+cls_method_handle_t h_journal_get_client;
cls_method_handle_t h_journal_client_register;
+cls_method_handle_t h_journal_client_update;
cls_method_handle_t h_journal_client_unregister;
cls_method_handle_t h_journal_client_commit;
cls_method_handle_t h_journal_client_list;
return 0;
}
+/**
+ * Input:
+ * @param id (string) - unique client id
+ *
+ * Output:
+ * cls::journal::Client
+ * @returns 0 on success, negative error code on failure
+ */
+int journal_get_client(cls_method_context_t hctx, bufferlist *in,
+ bufferlist *out) {
+ std::string id;
+ try {
+ bufferlist::iterator iter = in->begin();
+ ::decode(id, iter);
+ } catch (const buffer::error &err) {
+ CLS_ERR("failed to decode input parameters: %s", err.what());
+ return -EINVAL;
+ }
+
+ std::string key(key_from_client_id(id));
+ cls::journal::Client client;
+ int r = read_key(hctx, key, &client);
+ if (r < 0) {
+ return r;
+ }
+
+ ::encode(client, *out);
+ return 0;
+}
+
/**
* Input:
* @param id (string) - unique client id
return 0;
}
+/**
+ * Input:
+ * @param id (string) - unique client id
+ * @param data (bufferlist) - opaque data associated to client
+ *
+ * Output:
+ * @returns 0 on success, negative error code on failure
+ */
+int journal_client_update(cls_method_context_t hctx, bufferlist *in,
+ bufferlist *out) {
+ std::string id;
+ bufferlist data;
+ try {
+ bufferlist::iterator iter = in->begin();
+ ::decode(id, iter);
+ ::decode(data, iter);
+ } catch (const buffer::error &err) {
+ CLS_ERR("failed to decode input parameters: %s", err.what());
+ return -EINVAL;
+ }
+
+ std::string key(key_from_client_id(id));
+ cls::journal::Client client;
+ int r = read_key(hctx, key, &client);
+ if (r < 0) {
+ return r;
+ }
+
+ client.data = data;
+ r = write_key(hctx, key, client);
+ if (r < 0) {
+ return r;
+ }
+ return 0;
+}
+
/**
* Input:
* @param id (string) - unique client id
CLS_METHOD_RD | CLS_METHOD_WR,
journal_set_active_set,
&h_journal_set_active_set);
+
+ cls_register_cxx_method(h_class, "get_client",
+ CLS_METHOD_RD,
+ journal_get_client, &h_journal_get_client);
cls_register_cxx_method(h_class, "client_register",
CLS_METHOD_RD | CLS_METHOD_WR,
journal_client_register, &h_journal_client_register);
+ cls_register_cxx_method(h_class, "client_update",
+ CLS_METHOD_RD | CLS_METHOD_WR,
+ journal_client_update, &h_journal_client_update);
cls_register_cxx_method(h_class, "client_unregister",
CLS_METHOD_RD | CLS_METHOD_WR,
journal_client_unregister,
cls_register_cxx_method(h_class, "client_list",
CLS_METHOD_RD,
journal_client_list, &h_journal_client_list);
+
cls_register_cxx_method(h_class, "get_next_tag_tid",
CLS_METHOD_RD,
journal_get_next_tag_tid,
op->exec("journal", "set_active_set", bl);
}
+int get_client(librados::IoCtx &ioctx, const std::string &oid,
+ const std::string &id, cls::journal::Client *client) {
+ librados::ObjectReadOperation op;
+ get_client_start(&op, id);
+
+ bufferlist out_bl;
+ int r = ioctx.operate(oid, &op, &out_bl);
+ if (r < 0) {
+ return r;
+ }
+
+ bufferlist::iterator iter = out_bl.begin();
+ r = get_client_finish(&iter, client);
+ if (r < 0) {
+ return r;
+ }
+ return 0;
+}
+
+void get_client_start(librados::ObjectReadOperation *op,
+ const std::string &id) {
+ bufferlist bl;
+ ::encode(id, bl);
+ op->exec("journal", "get_client", bl);
+}
+
+int get_client_finish(bufferlist::iterator *iter,
+ cls::journal::Client *client) {
+ try {
+ ::decode(*client, *iter);
+ } catch (const buffer::error &err) {
+ return -EBADMSG;
+ }
+ return 0;
+}
+
+int client_register(librados::IoCtx &ioctx, const std::string &oid,
+ const std::string &id, const bufferlist &data) {
+ librados::ObjectWriteOperation op;
+ client_register(&op, id, data);
+ return ioctx.operate(oid, &op);
+}
+
void client_register(librados::ObjectWriteOperation *op,
const std::string &id, const bufferlist &data) {
bufferlist bl;
op->exec("journal", "client_register", bl);
}
-int client_register(librados::IoCtx &ioctx, const std::string &oid,
- const std::string &id, const bufferlist &data) {
+int client_update(librados::IoCtx &ioctx, const std::string &oid,
+ const std::string &id, const bufferlist &data) {
librados::ObjectWriteOperation op;
- client_register(&op, id, data);
+ client_update(&op, id, data);
return ioctx.operate(oid, &op);
}
+void client_update(librados::ObjectWriteOperation *op,
+ const std::string &id, const bufferlist &data) {
+ bufferlist bl;
+ ::encode(id, bl);
+ ::encode(data, bl);
+ op->exec("journal", "client_update", bl);
+}
+
int client_unregister(librados::IoCtx &ioctx, const std::string &oid,
const std::string &id) {
bufferlist inbl;
void set_active_set(librados::ObjectWriteOperation *op, uint64_t object_set);
// journal client helpers
-void client_register(librados::ObjectWriteOperation *op,
- const std::string &id, const bufferlist &data);
+int get_client(librados::IoCtx &ioctx, const std::string &oid,
+ const std::string &id, cls::journal::Client *client);
+void get_client_start(librados::ObjectReadOperation *op,
+ const std::string &id);
+int get_client_finish(bufferlist::iterator *iter,
+ cls::journal::Client *client);
+
int client_register(librados::IoCtx &ioctx, const std::string &oid,
const std::string &id, const bufferlist &data);
+void client_register(librados::ObjectWriteOperation *op,
+ const std::string &id, const bufferlist &data);
+
+int client_update(librados::IoCtx &ioctx, const std::string &oid,
+ const std::string &id, const bufferlist &data);
+void client_update(librados::ObjectWriteOperation *op,
+ const std::string &id, const bufferlist &data);
+
int client_unregister(librados::IoCtx &ioctx, const std::string &oid,
const std::string &id);
+
void client_commit(librados::ObjectWriteOperation *op, const std::string &id,
const cls::journal::ObjectSetPosition &commit_position);
+
int client_list(librados::IoCtx &ioctx, const std::string &oid,
std::set<cls::journal::Client> *clients);
ASSERT_EQ(-EEXIST, client::create(ioctx, oid, 3, 5, ioctx.get_id()));
}
+TEST_F(TestClsJournal, GetClient) {
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+
+ std::string oid = get_temp_image_name();
+
+ Client client;
+ ASSERT_EQ(-ENOENT, client::get_client(ioctx, oid, "id", &client));
+
+ bufferlist data;
+ data.append(std::string('1', 128));
+ ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", data));
+
+ ASSERT_EQ(0, client::get_client(ioctx, oid, "id1", &client));
+ Client expected_client("id1", data);
+ ASSERT_EQ(expected_client, client);
+}
+
TEST_F(TestClsJournal, ClientRegister) {
librados::IoCtx ioctx;
ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
ASSERT_EQ(-EEXIST, client::client_register(ioctx, oid, "id1", bufferlist()));
}
+TEST_F(TestClsJournal, ClientUpdate) {
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+
+ std::string oid = get_temp_image_name();
+
+ ASSERT_EQ(-ENOENT, client::client_update(ioctx, oid, "id1", bufferlist()));
+
+ ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", bufferlist()));
+
+ bufferlist data;
+ data.append(std::string('1', 128));
+ ASSERT_EQ(0, client::client_update(ioctx, oid, "id1", data));
+
+ Client client;
+ ASSERT_EQ(0, client::get_client(ioctx, oid, "id1", &client));
+ Client expected_client("id1", data);
+ ASSERT_EQ(expected_client, client);
+}
+
TEST_F(TestClsJournal, ClientUnregister) {
librados::IoCtx ioctx;
ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));