From 57f423ba696b3dbc2cfcd29a7682097649450cbe Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Wed, 18 May 2011 18:37:12 -0700 Subject: [PATCH] librados: add rados_getxattrs API for C bindings Support getxattrs in the Rados C API. Also add a test of getattrs to testrados.c Signed-off-by: Colin McCabe --- src/include/rados/librados.h | 6 +++ src/librados.cc | 71 +++++++++++++++++++++++++++++++++++- src/testrados.c | 63 ++++++++++++++++++++++++++++---- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index c55a0960b7b1d..fdf14e9885080 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -32,6 +32,7 @@ typedef void *rados_t; typedef void *rados_ioctx_t; typedef void *rados_list_ctx_t; typedef uint64_t rados_snap_t; +typedef void *rados_xattrs_iter_t; struct rados_pool_stat_t { uint64_t num_bytes; // in bytes @@ -150,6 +151,11 @@ int rados_getxattr(rados_ioctx_t io, const char *o, const char *name, char *buf, int rados_setxattr(rados_ioctx_t io, const char *o, const char *name, const char *buf, size_t len); int rados_rmxattr(rados_ioctx_t io, const char *o, const char *name); +int rados_getxattrs(rados_ioctx_t io, const char *oid, rados_xattrs_iter_t *iter); +int rados_getxattrs_next(rados_xattrs_iter_t iter, const char **name, + const char **val, int *len); +void rados_getxattrs_end(rados_xattrs_iter_t iter); + /* misc */ int rados_stat(rados_ioctx_t io, const char *o, uint64_t *psize, time_t *pmtime); int rados_tmap_update(rados_ioctx_t io, const char *o, const char *cmdbuf, size_t cmdbuflen); diff --git a/src/librados.cc b/src/librados.cc index 74e6934d1b77f..8348900ee5e61 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -1895,8 +1895,6 @@ setxattr(IoCtxImpl& io, const object_t& oid, const char *name, bufferlist& bl) int librados::RadosClient:: getxattrs(IoCtxImpl& io, const object_t& oid, map& attrset) { - utime_t ut = g_clock.now(); - Mutex mylock("RadosClient::getexattrs::mylock"); Cond cond; bool done; @@ -3242,6 +3240,75 @@ extern "C" int rados_getxattr(rados_ioctx_t io, const char *o, const char *name, return ret; } +class RadosXattrsIter { +public: + RadosXattrsIter() + : val(NULL) + { + i = attrset.end(); + } + ~RadosXattrsIter() + { + free(val); + val = NULL; + } + std::map attrset; + std::map::iterator i; + char *val; +}; + +extern "C" int rados_getxattrs(rados_ioctx_t io, const char *oid, + rados_xattrs_iter_t *iter) +{ + RadosXattrsIter *it = new RadosXattrsIter(); + if (!it) + return ENOMEM; + librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; + object_t obj(oid); + int ret = ctx->client->getxattrs(*ctx, obj, it->attrset); + if (ret) { + delete it; + return ret; + } + it->i = it->attrset.begin(); + + RadosXattrsIter **iret = (RadosXattrsIter**)iter; + *iret = it; + *iter = it; + return 0; +} + +extern "C" int rados_getxattrs_next(rados_xattrs_iter_t iter, + const char **name, const char **val, int *len) +{ + RadosXattrsIter *it = (RadosXattrsIter*)iter; + if (it->i == it->attrset.end()) { + *name = NULL; + *val = NULL; + *len = 0; + return 0; + } + free(it->val); + const std::string &s(it->i->first); + *name = s.c_str(); + bufferlist &bl(it->i->second); + size_t bl_len = bl.length(); + it->val = (char*)malloc(bl_len); + if (!it->val) + return ENOMEM; + memcpy(it->val, bl.c_str(), bl_len); + *val = it->val; + *len = bl_len; + ++it->i; + return 0; +} + +extern "C" void rados_getxattrs_end(rados_xattrs_iter_t iter) +{ + RadosXattrsIter *it = (RadosXattrsIter*)iter; + delete it; +} + extern "C" int rados_setxattr(rados_ioctx_t io, const char *o, const char *name, const char *buf, size_t len) { librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; diff --git a/src/testrados.c b/src/testrados.c index 22e7734914d25..5f8345bcc6e3d 100644 --- a/src/testrados.c +++ b/src/testrados.c @@ -1,4 +1,4 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system @@ -7,9 +7,9 @@ * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software + * License version 2.1, as published by the Free Software * Foundation. See file COPYING. - * + * */ #include "include/rados/librados.h" @@ -21,7 +21,7 @@ static void do_rados_setxattr(rados_ioctx_t io_ctx, const char *oid, const char *key, const char *val) { - int ret = rados_setxattr(io_ctx, oid, key, val, strlen(val)); + int ret = rados_setxattr(io_ctx, oid, key, val, strlen(val) + 1); if (ret < 0) { printf("rados_setxattr failed with error %d\n", ret); exit(1); @@ -48,7 +48,53 @@ static void do_rados_getxattr(rados_ioctx_t io_ctx, const char *oid, printf("rados_getxattr %s=%s\n", key, buf); } -int main(int argc, const char **argv) +static void do_rados_getxattrs(rados_ioctx_t io_ctx, const char *oid, + const char **exkeys, const char **exvals) +{ + rados_xattrs_iter_t iter; + int len, nval = 0, i, nfound = 0, ret = 0; + + for (i = 0; exvals[i]; ++i) { + ++nval; + } + ret = rados_getxattrs(io_ctx, oid, &iter); + if (ret) { + printf("rados_getxattrs(%s) failed with error %d\n", oid, ret); + exit(1); + } + while (1) { + const char *key, *val; + ret = rados_getxattrs_next(iter, &key, &val, &len); + if (ret) { + printf("rados_getxattrs(%s): rados_getxattrs_next " + "returned error %d\n", oid, ret); + exit(1); + } + if (!key) + break; + for (i = 0; i < nval; ++i) { + if (strcmp(exkeys[i], key)) + continue; + if ((len == strlen(exvals[i]) + 1) && (!strcmp(exvals[i], val))) { + nfound++; + break; + } + printf("rados_getxattrs(%s): got key %s, but the " + "value was %s rather than %s.\n", + oid, key, val, exvals[i]); + exit(1); + } + } + if (nfound != nval) { + printf("rados_getxattrs(%s): only found %d extended attributes. " + "Expected %d\n", oid, nfound, nval); + exit(1); + } + rados_getxattrs_end(iter); + printf("rados_getxattrs(%s)\n", oid); +} + +int main(int argc, const char **argv) { char tmp[32]; int i, r; @@ -77,7 +123,7 @@ int main(int argc, const char **argv) exit(1); } - // Can we change it? + // Can we change it? if (rados_conf_set(cl, "log to stderr", "2")) { printf("error: error setting log_to_stderr\n"); exit(1); @@ -172,6 +218,9 @@ int main(int argc, const char **argv) do_rados_getxattr(io_ctx, oid, "a", "1"); do_rados_getxattr(io_ctx, oid, "b", "2"); do_rados_getxattr(io_ctx, oid, "c", "3"); + const char *exkeys[] = { "a", "b", "c", NULL }; + const char *exvals[] = { "1", "2", "3", NULL }; + do_rados_getxattrs(io_ctx, oid, exkeys, exvals); uint64_t size; time_t mtime; @@ -216,7 +265,7 @@ int main(int argc, const char **argv) printf("rados_stat_pool = %d, %lld KB, %lld objects\n", r, (long long)st.num_kb, (long long)st.num_objects); /* delete a pool */ - printf("rados_delete_pool = %d\n", r); + printf("rados_delete_pool = %d\n", r); rados_ioctx_destroy(io_ctx); r = rados_pool_delete(cl, "foo"); -- 2.39.5