From 5eda2859d03a93359c04e706ddd0419aac50ef61 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 4 Feb 2016 20:32:54 -0500 Subject: [PATCH] cls_journal: new get_client / client_update methods Signed-off-by: Jason Dillaman --- src/cls/journal/cls_journal.cc | 76 ++++++++++++++++++++++++ src/cls/journal/cls_journal_client.cc | 57 +++++++++++++++++- src/cls/journal/cls_journal_client.h | 19 +++++- src/test/cls_journal/test_cls_journal.cc | 38 ++++++++++++ 4 files changed, 185 insertions(+), 5 deletions(-) diff --git a/src/cls/journal/cls_journal.cc b/src/cls/journal/cls_journal.cc index 1e8d8da21a0..f87c2b2ad8a 100644 --- a/src/cls/journal/cls_journal.cc +++ b/src/cls/journal/cls_journal.cc @@ -24,7 +24,9 @@ cls_method_handle_t h_journal_get_minimum_set; 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; @@ -493,6 +495,36 @@ int journal_set_active_set(cls_method_context_t hctx, bufferlist *in, 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 @@ -531,6 +563,42 @@ int journal_client_register(cls_method_context_t hctx, bufferlist *in, 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 @@ -994,9 +1062,16 @@ void CEPH_CLS_API __cls_init() 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, @@ -1007,6 +1082,7 @@ void CEPH_CLS_API __cls_init() 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, diff --git a/src/cls/journal/cls_journal_client.cc b/src/cls/journal/cls_journal_client.cc index c72b6b93edb..32959642eaf 100644 --- a/src/cls/journal/cls_journal_client.cc +++ b/src/cls/journal/cls_journal_client.cc @@ -223,6 +223,49 @@ void set_active_set(librados::ObjectWriteOperation *op, uint64_t object_set) { 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; @@ -231,13 +274,21 @@ void client_register(librados::ObjectWriteOperation *op, 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; diff --git a/src/cls/journal/cls_journal_client.h b/src/cls/journal/cls_journal_client.h index a6d595d36d2..37b0143b2ee 100644 --- a/src/cls/journal/cls_journal_client.h +++ b/src/cls/journal/cls_journal_client.h @@ -33,14 +33,29 @@ void set_minimum_set(librados::ObjectWriteOperation *op, uint64_t object_set); 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 *clients); diff --git a/src/test/cls_journal/test_cls_journal.cc b/src/test/cls_journal/test_cls_journal.cc index bde728ffe91..3a26e8f66cd 100644 --- a/src/test/cls_journal/test_cls_journal.cc +++ b/src/test/cls_journal/test_cls_journal.cc @@ -192,6 +192,24 @@ TEST_F(TestClsJournal, CreateDuplicate) { 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)); @@ -217,6 +235,26 @@ TEST_F(TestClsJournal, ClientRegisterDuplicate) { 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)); -- 2.39.5