From 32c913a2f07a37a917491067cf13d00485ea4db3 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Thu, 24 Feb 2011 03:30:23 -0800 Subject: [PATCH] Some tweaks for the librados C API rados_reopen_log: should take a cluster parameter. Add rados_pool_list, rados_pool_list_free. rados_snap_set_read -> rados_pool_snap_set_read rados_snap_set_write_context -> rados_pool_selfmanaged_snap_set_write_ctx write/write_full/etc: re-arrange parameter order to be the same as pwrite(2). Change interface of rados_pool_list a bit Signed-off-by: Colin McCabe --- src/include/rados/librados.h | 38 ++++++++++++++++---------- src/librados.cc | 53 ++++++++++++++++++++++++++---------- src/testlibrbd.c | 2 +- src/testrados.c | 45 ++++++++++++++++++++---------- 4 files changed, 93 insertions(+), 45 deletions(-) diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index eda83d462d476..d220cad2747f6 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -76,7 +76,7 @@ int rados_conf_set(rados_t cluster, const char *option, const char *value); * It is also good practice to call this from your SIGHUP signal handler, so that users can send you * a SIGHUP to reopen the log. */ -void rados_reopen_log(void); +void rados_reopen_log(rados_t cluster); /* Returns a configuration value as a string. * If len is positive, that is the maximum number of bytes we'll write into the @@ -84,18 +84,25 @@ void rados_reopen_log(void); * Returns 0 on success, error code otherwise. Returns ENAMETOOLONG if the * buffer is too short. */ int rados_conf_get(rados_t cluster, const char *option, char *buf, int len); -int rados_conf_get_alloc(rados_t cluster, const char *option, char **buf); /* pools */ + +/* Gets a list of pool names as NULL-terminated strings. + * The pool names will be placed in the supplied buffer one after another. + * After the last pool name, there will be two 0 bytes in a row. + * + * If len is too short to fit all the pool name entries we need, we will fill + * as much as we can. + * Returns the length of the buffer we would need to list all pools. + */ +int rados_pool_list(rados_t cluster, char *buf, int len); + int rados_pool_open(rados_t cluster, const char *name, rados_pool_t *pool); int rados_pool_close(rados_pool_t pool); int rados_pool_lookup(rados_t cluster, const char *name); int rados_pool_stat(rados_pool_t pool, struct rados_pool_stat_t *stats); -void rados_snap_set_read(rados_pool_t pool, rados_snap_t snap); -int rados_snap_set_write_context(rados_pool_t pool, rados_snap_t seq, rados_snap_t *snaps, int num_snaps); - int rados_pool_create(rados_t cluster, const char *name); int rados_pool_create_with_auid(rados_t cluster, const char *name, uint64_t auid); int rados_pool_create_with_crush_rule(rados_t cluster, const char *name, __u8 crush_rule); @@ -115,8 +122,11 @@ int rados_pool_snap_create(rados_pool_t pool, const char *snapname); int rados_pool_snap_remove(rados_pool_t pool, const char *snapname); int rados_pool_snap_rollback_object(rados_pool_t pool, const char *oid, const char *snapname); +void rados_pool_snap_set_read(rados_pool_t pool, rados_snap_t snap); int rados_pool_selfmanaged_snap_create(rados_pool_t pool, uint64_t *snapid); int rados_pool_selfmanaged_snap_remove(rados_pool_t pool, uint64_t snapid); +int rados_pool_selfmanaged_snap_set_write_ctx(rados_pool_t pool, rados_snap_t seq, rados_snap_t *snaps, int num_snaps); + int rados_pool_snap_list(rados_pool_t pool, rados_snap_t *snaps, int maxlen); int rados_pool_snap_lookup(rados_pool_t pool, const char *name, rados_snap_t *id); int rados_pool_snap_get_name(rados_pool_t pool, rados_snap_t id, char *name, int maxlen); @@ -124,9 +134,9 @@ int rados_pool_snap_get_name(rados_pool_t pool, rados_snap_t id, char *name, int /* sync io */ uint64_t rados_get_last_version(rados_pool_t pool); -int rados_write(rados_pool_t pool, const char *oid, off_t off, const char *buf, size_t len); -int rados_write_full(rados_pool_t pool, const char *oid, off_t off, const char *buf, size_t len); -int rados_read(rados_pool_t pool, const char *oid, off_t off, char *buf, size_t len); +int rados_write(rados_pool_t pool, const char *oid, const char *buf, size_t len, off_t off); +int rados_write_full(rados_pool_t pool, const char *oid, const char *buf, size_t len, off_t off); +int rados_read(rados_pool_t pool, const char *oid, char *buf, size_t len, off_t off); int rados_remove(rados_pool_t pool, const char *oid); int rados_trunc(rados_pool_t pool, const char *oid, size_t size); @@ -155,14 +165,14 @@ int rados_aio_get_return_value(rados_completion_t c); uint64_t rados_aio_get_obj_ver(rados_completion_t c); void rados_aio_release(rados_completion_t c); int rados_aio_write(rados_pool_t pool, const char *oid, - off_t off, const char *buf, size_t len, - rados_completion_t completion); + rados_completion_t completion, + const char *buf, size_t len, off_t off); int rados_aio_write_full(rados_pool_t pool, const char *oid, - off_t off, const char *buf, size_t len, - rados_completion_t completion); + rados_completion_t completion, + const char *buf, size_t len, off_t off); int rados_aio_read(rados_pool_t pool, const char *oid, - off_t off, char *buf, size_t len, - rados_completion_t completion); + rados_completion_t completion, + char *buf, size_t len, off_t off); /* watch/notify */ typedef void (*rados_watchcb_t)(uint8_t opcode, uint64_t ver, void *arg); diff --git a/src/librados.cc b/src/librados.cc index 626009ec9d4b0..a819ebb0b3cce 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -2443,7 +2443,7 @@ extern "C" int rados_conf_set(rados_t cluster, const char *option, const char *v return g_conf.set_val(option, value); } -extern "C" void rados_reopen_log(void) +extern "C" void rados_reopen_log(rados_t cluster) { sighup_handler(SIGHUP); } @@ -2456,17 +2456,40 @@ extern "C" int rados_conf_get(rados_t cluster, const char *option, char *buf, in return g_conf.get_val(option, &tmp, len); } -extern "C" int rados_conf_get_alloc(rados_t cluster, const char *option, char **buf) -{ - return g_conf.get_val(option, buf, -1); -} - extern "C" int rados_pool_lookup(rados_t cluster, const char *name) { RadosClient *radosp = (RadosClient *)cluster; return radosp->lookup_pool(name); } +extern "C" int rados_pool_list(rados_t cluster, char *buf, int len) +{ + RadosClient *client = (RadosClient *)cluster; + std::list pools; + client->list_pools(pools); + + char *b = buf; + if (b) + memset(b, 0, len); + int needed = 0; + std::list::const_iterator i = pools.begin(); + std::list::const_iterator p_end = pools.end(); + for (; i != p_end; ++i) { + if (len <= 0) + break; + int rl = i->length() + 1; + strncat(b, i->c_str(), len - 2); // leave space for two NULLs + needed += rl; + len -= rl; + b += rl; + } + for (; i != p_end; ++i) { + int rl = i->length() + 1; + needed += rl; + } + return needed + 1; +} + extern "C" int rados_pool_open(rados_t cluster, const char *name, rados_pool_t *pool) { RadosClient *radosp = (RadosClient *)cluster; @@ -2533,7 +2556,7 @@ extern "C" int rados_snap_set_write_context(rados_pool_t pool, rados_snap_t seq, return ctx->set_snap_write_context((snapid_t)seq, snv); } -extern "C" int rados_write(rados_pool_t pool, const char *o, off_t off, const char *buf, size_t len) +extern "C" int rados_write(rados_pool_t pool, const char *o, const char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; object_t oid(o); @@ -2542,7 +2565,7 @@ extern "C" int rados_write(rados_pool_t pool, const char *o, off_t off, const ch return ctx->client->write(*ctx, oid, off, bl, len); } -extern "C" int rados_write_full(rados_pool_t pool, const char *o, off_t off, const char *buf, size_t len) +extern "C" int rados_write_full(rados_pool_t pool, const char *o, const char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; object_t oid(o); @@ -2565,7 +2588,7 @@ extern "C" int rados_remove(rados_pool_t pool, const char *o) return ctx->client->remove(*ctx, oid); } -extern "C" int rados_read(rados_pool_t pool, const char *o, off_t off, char *buf, size_t len) +extern "C" int rados_read(rados_pool_t pool, const char *o, char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; int ret; @@ -2868,8 +2891,8 @@ extern "C" void rados_aio_release(rados_completion_t c) } extern "C" int rados_aio_read(rados_pool_t pool, const char *o, - off_t off, char *buf, size_t len, - rados_completion_t completion) + rados_completion_t completion, + char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; object_t oid(o); @@ -2877,8 +2900,8 @@ extern "C" int rados_aio_read(rados_pool_t pool, const char *o, } extern "C" int rados_aio_write(rados_pool_t pool, const char *o, - off_t off, const char *buf, size_t len, - rados_completion_t completion) + rados_completion_t completion, + const char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; object_t oid(o); @@ -2888,8 +2911,8 @@ extern "C" int rados_aio_write(rados_pool_t pool, const char *o, } extern "C" int rados_aio_write_full(rados_pool_t pool, const char *o, - off_t off, const char *buf, size_t len, - rados_completion_t completion) + rados_completion_t completion, + const char *buf, size_t len, off_t off) { RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool; object_t oid(o); diff --git a/src/testlibrbd.c b/src/testlibrbd.c index 72e1242f36f69..ab199db312646 100644 --- a/src/testlibrbd.c +++ b/src/testlibrbd.c @@ -263,7 +263,7 @@ int main(int argc, const char **argv) rbd_image_t image; assert(rados_create(&cluster, NULL) == 0); assert(rados_conf_read_file(cluster, "/etc/ceph/ceph.conf") == 0); - rados_reopen_log(); + rados_reopen_log(cluster); assert(rados_pool_open(cluster, TEST_POOL, &pool) == 0); test_ls(pool, 0); test_create_and_stat(pool, TEST_IMAGE, MB_BYTES(1)); diff --git a/src/testrados.c b/src/testrados.c index 1517f0f6ebcbd..7ee3cae4620ac 100644 --- a/src/testrados.c +++ b/src/testrados.c @@ -21,7 +21,6 @@ int main(int argc, const char **argv) { char tmp[32]; - char *tmp2; int i, r; rados_t cl; @@ -48,19 +47,12 @@ int main(int argc, const char **argv) exit(1); } - // Testing the version that uses malloc(). - if (rados_conf_get_alloc(cl, "log to stderr", &tmp2)) { - printf("error: failed to read log_to_stderr from config\n"); - exit(1); - } - free(tmp2); - // Can we change it? if (rados_conf_set(cl, "log to stderr", "2")) { printf("error: error setting log_to_stderr\n"); exit(1); } - rados_reopen_log(); + rados_reopen_log(cl); if (rados_conf_get(cl, "log to stderr", tmp, sizeof(tmp))) { printf("error: failed to read log_to_stderr from config\n"); exit(1); @@ -83,6 +75,29 @@ int main(int argc, const char **argv) r = rados_pool_open(cl, "foo", &pool); printf("rados_pool_open = %d, pool = %p\n", r, pool); + /* list all pools */ + { + int buf_sz = rados_pool_list(cl, NULL, 0); + printf("need buffer size of %d\n", buf_sz); + char buf[buf_sz]; + int r = rados_pool_list(cl, buf, buf_sz); + if (r != buf_sz) { + printf("buffer size mismatch: got %d the first time, but %d " + "the second.\n", buf_sz, r); + exit(1); + } + const char *b = buf; + printf("begin pools.\n"); + while (1) { + if (b[0] == '\0') + break; + printf(" pool: '%s'\n", b); + b += strlen(b) + 1; + }; + printf("end pools.\n"); + } + + /* stat */ struct rados_pool_stat_t st; r = rados_pool_stat(pool, &st); @@ -110,9 +125,9 @@ int main(int argc, const char **argv) time(&tm); snprintf(buf, 128, "%s", ctime(&tm)); const char *oid = "foo_object"; - r = rados_write(pool, oid, 0, buf, strlen(buf) + 1); + r = rados_write(pool, oid, buf, strlen(buf) + 1, 0); printf("rados_write = %d\n", r); - r = rados_read(pool, oid, 0, buf2, sizeof(buf2)); + r = rados_read(pool, oid, buf2, sizeof(buf2), 0); printf("rados_read = %d\n", r); if (memcmp(buf, buf2, r)) printf("*** content mismatch ***\n"); @@ -136,7 +151,7 @@ int main(int argc, const char **argv) /* exec */ rados_exec(pool, oid, "crypto", "md5", buf, strlen(buf) + 1, buf, 128); printf("exec result=%s\n", buf); - r = rados_read(pool, oid, 0, buf2, 128); + r = rados_read(pool, oid, buf2, 128, 0); printf("read result=%s\n", buf2); printf("size=%d\n", r); @@ -144,8 +159,8 @@ int main(int argc, const char **argv) rados_completion_t a, b; rados_aio_create_completion(0, 0, 0, &a); rados_aio_create_completion(0, 0, 0, &b); - rados_aio_write(pool, "a", 0, buf, 100, a); - rados_aio_write(pool, "../b/bb_bb_bb\\foo\\bar", 0, buf, 100, b); + rados_aio_write(pool, "a", a, buf, 100, 0); + rados_aio_write(pool, "../b/bb_bb_bb\\foo\\bar", b, buf, 100, 0); rados_aio_wait_for_safe(a); printf("a safe\n"); rados_aio_wait_for_safe(b); @@ -153,7 +168,7 @@ int main(int argc, const char **argv) rados_aio_release(a); rados_aio_release(b); - rados_read(pool, "../b/bb_bb_bb\\foo\\bar", 0, buf2, 128); + rados_read(pool, "../b/bb_bb_bb\\foo\\bar", buf2, 128, 0); /* list objects */ rados_list_ctx_t h; -- 2.39.5