]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: add rados_getxattrs API for C bindings
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 19 May 2011 01:37:12 +0000 (18:37 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 19 May 2011 19:46:46 +0000 (12:46 -0700)
Support getxattrs in the Rados C API.

Also add a test of getattrs to testrados.c

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/include/rados/librados.h
src/librados.cc
src/testrados.c

index c55a0960b7b1de27dc5bdf839c421299f04d4151..fdf14e9885080198fdbc0f7e87addfaedb5bfa6b 100644 (file)
@@ -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);
index 74e6934d1b77fd6f991f484a8efde8c936fd7f3a..8348900ee5e61bf25faa06043de569c37c4bd7a7 100644 (file)
@@ -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<std::string, bufferlist>& 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<std::string, bufferlist> attrset;
+  std::map<std::string, bufferlist>::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;
index 22e7734914d25ccf137216845ec27986072d65b6..5f8345bcc6e3dbc716e5423203280d02890eeff4 100644 (file)
@@ -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");