]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rados: supply a C++ api
authorYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 20 May 2009 20:35:50 +0000 (13:35 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 20 May 2009 20:36:12 +0000 (13:36 -0700)
src/Makefile.am
src/include/librados.h
src/librados.cc
src/testrados.c
src/testradospp.cc [new file with mode: 0644]

index 7d499eb605726b9827dadd10d5219f40f60750e2..c06f1a481c063d8b0116dc159a59ee9156aafb20 100644 (file)
@@ -49,7 +49,7 @@ bin_PROGRAMS = \
        ceph cconf \
        mkmonfs monmaptool osdmaptool crushtool \
        streamtest dupstore dumpjournal testmsgr \
-       testrados
+       testrados testradospp
 
 sbin_PROGRAMS = \
        mount.ceph
@@ -113,6 +113,8 @@ lib_LTLIBRARIES += librados.la
 
 testrados_SOURCES = testrados.c
 testrados_LDADD = librados.la libcrush.la
+testradospp_SOURCES = testradospp.cc
+testradospp_LDADD = librados.la libcrush.la
 
 
 ## object classes
index 22ed6e44889b1e837ec3d3958f2585dd37be4205..ffb0535517ef6167a06f4f5f9108cc41161bd96b 100644 (file)
@@ -2,6 +2,9 @@
 #define __LIBRADOS_H
 
 #ifdef __cplusplus
+
+#include "include/types.h"
+
 extern "C" {
 #endif
 
@@ -23,13 +26,33 @@ int rados_open_pool(const char *name, rados_pool_t *pool);
 int rados_close_pool(rados_pool_t pool);
 
 /* read/write objects */
-int rados_write(rados_pool_t pool, struct ceph_object *oid, const char *buf, off_t off, size_t len);
-int rados_read(rados_pool_t pool, struct ceph_object *oid, char *buf, off_t off, size_t len);
+int rados_write(rados_pool_t pool, struct ceph_object *oid, off_t off, const char *buf, size_t len);
+int rados_read(rados_pool_t pool, struct ceph_object *oid, off_t off, char *buf, size_t len);
 int rados_exec(rados_pool_t pool, struct ceph_object *o, const char *cls, const char *method,
               const char *in_buf, size_t in_len, char *buf, size_t out_len);
 
 #ifdef __cplusplus
 }
+
+class RadosClient;
+
+class Rados
+{
+  RadosClient *client;
+public:
+  Rados();
+  ~Rados();
+  bool initialize(int argc, const char *argv[]);
+
+  int open_pool(const char *name, rados_pool_t *pool);
+  int close_pool(rados_pool_t pool);
+
+  int write(rados_pool_t pool, object_t& oid, off_t off, bufferlist& bl, size_t len);
+  int read(rados_pool_t pool, object_t& oid, off_t off, bufferlist& bl, size_t len);
+
+  int exec(rados_pool_t pool, object_t& oid, const char *cls, const char *method,
+             bufferlist& inbl, size_t in_len, bufferlist& outbl, size_t out_len);
+};
 #endif
 
 #endif
index e0a2092698771d4cc4617e631ec64729c86f8dee..ffbdce0832d5fcf952328fffb01d57d6cc58dcdc 100644 (file)
@@ -40,6 +40,8 @@ using namespace std;
 #include "messages/MClientMount.h"
 #include "messages/MClientMountAck.h"
 
+#include "include/librados.h"
+
 
 class RadosClient : public Dispatcher
 {
@@ -58,7 +60,7 @@ class RadosClient : public Dispatcher
   Cond cond;
 
 public:
-  RadosClient() : messenger(NULL), mc(NULL), lock("c3") {}
+  RadosClient() : messenger(NULL), mc(NULL), lock("radosclient") {}
   ~RadosClient();
   bool init();
 
@@ -66,10 +68,10 @@ public:
     return osdmap.lookup_pg_pool_name(name);
   }
 
-  int write(int pool, object_t& oid, const char *buf, off_t off, size_t len);
-  int read(int pool, object_t& oid, char *buf, off_t off, size_t len);
+  int write(int pool, object_t& oid, off_t off, bufferlist& bl, size_t len);
+  int read(int pool, object_t& oid, off_t off, bufferlist& bl, size_t len);
 
-  int exec(int pool, object_t& oid, const char *cls, const char *method, const char *inbuf, size_t in_len, char *buf, size_t out_len);
+  int exec(int pool, object_t& oid, const char *cls, const char *method, bufferlist& inbl, size_t in_len, bufferlist& outbl, size_t out_len);
 };
 
 bool RadosClient::init()
@@ -81,7 +83,7 @@ bool RadosClient::init()
     return false;
 
   rank.bind();
-  cout << "starting c3." << g_conf.id
+  cout << "starting radosclient." << g_conf.id
        << " at " << rank.get_rank_addr() 
        << " fsid " << monmap.get_fsid()
        << std::endl;
@@ -181,10 +183,9 @@ bool RadosClient::_dispatch(Message *m)
   return true;
 }
 
-int RadosClient::write(int pool, object_t& oid, const char *buf, off_t off, size_t len)
+int RadosClient::write(int pool, object_t& oid, off_t off, bufferlist& bl, size_t len)
 {
   SnapContext snapc;
-  bufferlist bl;
   utime_t ut = g_clock.now();
 
   Mutex lock("RadosClient::write");
@@ -192,9 +193,9 @@ int RadosClient::write(int pool, object_t& oid, const char *buf, off_t off, size
   bool done;
   int r;
   Context *onack = new C_SafeCond(&lock, &cond, &done, &r);
-
+#if 0
   bl.append(&buf[off], len);
-
+#endif
   ceph_object_layout layout = objecter->osdmap->make_object_layout(oid, pool);
 
   dout(0) << "going to write" << dendl;
@@ -210,7 +211,7 @@ int RadosClient::write(int pool, object_t& oid, const char *buf, off_t off, size
   return len;
 }
 
-int RadosClient::exec(int pool, object_t& oid, const char *cls, const char *method, const char *inbuf, size_t in_len, char *buf, size_t out_len)
+int RadosClient::exec(int pool, object_t& oid, const char *cls, const char *method, bufferlist& inbl, size_t in_len, bufferlist& outbl, size_t out_len)
 {
   SnapContext snapc;
   utime_t ut = g_clock.now();
@@ -226,9 +227,7 @@ int RadosClient::exec(int pool, object_t& oid, const char *cls, const char *meth
   lock.Lock();
 
   ObjectRead rd;
-  bufferlist inbl, outbl;
 
-  inbl.append(inbuf, in_len);
   rd.rdcall(cls, method, inbl);
   objecter->read(oid, layout, rd, CEPH_NOSNAP, &outbl, 0, onack);
 
@@ -242,16 +241,12 @@ int RadosClient::exec(int pool, object_t& oid, const char *cls, const char *meth
   if (outbl.length() < out_len)
     out_len = outbl.length();
 
-  if (out_len)
-    memcpy(buf, outbl.c_str(), out_len);
-
   return out_len;
 }
 
-int RadosClient::read(int pool, object_t& oid, char *buf, off_t off, size_t len)
+int RadosClient::read(int pool, object_t& oid, off_t off, bufferlist& bl, size_t len)
 {
   SnapContext snapc;
-  bufferlist bl;
 
   Mutex lock("RadosClient::rdcall");
   Cond cond;
@@ -275,12 +270,75 @@ int RadosClient::read(int pool, object_t& oid, char *buf, off_t off, size_t len)
   if (bl.length() < len)
     len = bl.length();
 
-  if (len)
-    memcpy(buf, bl.c_str(), len);
-
   return len;
 }
 
+Rados::Rados() : client(NULL)
+{
+}
+
+Rados::~Rados()
+{
+  if (client)
+    delete client;
+  client = NULL;
+}
+
+bool Rados::initialize(int argc, const char *argv[])
+{
+ vector<const char*> args;
+
+  if (argc && argv) {
+    argv_to_vec(argc, argv, args);
+    env_to_vec(args);
+  }
+  common_init(args, "librados", false);
+
+  if (g_conf.clock_tare) g_clock.tare();
+
+  client = new RadosClient();
+  return client->init();
+}
+
+int Rados::write(rados_pool_t pool, object_t& oid, off_t off, bufferlist& bl, size_t len)
+{
+  if (!client)
+    return -EINVAL;
+
+  return client->write(pool, oid, off, bl, len);
+}
+
+int Rados::read(rados_pool_t pool, object_t& oid, off_t off, bufferlist& bl, size_t len)
+{
+  if (!client)
+    return -EINVAL;
+
+  return client->read(pool, oid, off, bl, len);
+}
+
+int Rados::exec(rados_pool_t pool, object_t& oid, const char *cls, const char *method,
+             bufferlist& inbl, size_t in_len, bufferlist& outbl, size_t out_len)
+{
+  if (!client)
+    return -EINVAL;
+
+  return client->exec(pool, oid, cls, method, inbl, in_len, outbl, out_len);
+}
+
+int Rados::open_pool(const char *name, rados_pool_t *pool)
+{
+  int poolid = client->lookup_pool(name);
+  if (poolid >= 0) {
+    *pool = poolid;
+    return 0;
+  }
+  return poolid;
+}
+
+int Rados::close_pool(rados_pool_t pool)
+{
+  return 0;
+}
 
 // ---------------------------------------------
 
@@ -355,22 +413,37 @@ extern "C" int rados_close_pool(rados_pool_t pool)
   return 0;
 }
 
-extern "C" int rados_write(rados_pool_t pool, ceph_object *o, const char *buf, off_t off, size_t len)
+extern "C" int rados_write(rados_pool_t pool, ceph_object *o, off_t off, const char *buf, size_t len)
 {
   object_t oid(*o);
-  return radosp->write(pool, oid, buf, off, len);
+  bufferlist bl;
+  bl.append(buf, len);
+  return radosp->write(pool, oid, off, bl, len);
 }
 
-extern "C" int rados_read(rados_pool_t pool, ceph_object *o, char *buf, off_t off, size_t len)
+extern "C" int rados_read(rados_pool_t pool, ceph_object *o, off_t off, char *buf, size_t len)
 {
+  int ret;
   object_t oid(*o);
-  return radosp->read(pool, oid, buf, off, len);
+  bufferlist bl;
+  ret = radosp->read(pool, oid, off, bl, len);
+  if (ret > 0)
+    memcpy(buf, bl.c_str(), ret);
+
+  return ret;
 }
 
 extern "C" int rados_exec(rados_pool_t pool, ceph_object *o, const char *cls, const char *method,
                          const char *inbuf, size_t in_len, char *buf, size_t out_len)
 {
   object_t oid(*o);
-  return radosp->exec(pool, oid, cls, method, inbuf, in_len, buf, out_len);
+  bufferlist inbl, outbl;
+  int ret;
+  inbl.append(inbuf, in_len);
+  ret = radosp->exec(pool, oid, cls, method, inbl, in_len, outbl, out_len);
+  if (ret > 0)
+    memcpy(buf, outbl.c_str(), ret);
+
+  return ret;
 }
 
index 87462a92389f6b466e38b17d854dded865f72846..44b3b5fc98a4fbc19c98ad5061fd54430f6ed2f5 100644 (file)
@@ -39,10 +39,10 @@ int main(int argc, const char **argv)
   int r = rados_open_pool("data", &pool);
   printf("open pool result = %d, pool = %d\n", r, pool);
 
-  rados_write(pool, &oid, buf, 0, strlen(buf) + 1);
+  rados_write(pool, &oid, 0, buf, strlen(buf) + 1);
   rados_exec(pool, &oid, "test", "foo", buf, strlen(buf) + 1, buf, 128);
   printf("exec result=%s\n", buf);
-  int size = rados_read(pool, &oid, buf2, 0, 128);
+  int size = rados_read(pool, &oid, 0, buf2, 128);
 
   rados_close_pool(pool);
 
diff --git a/src/testradospp.cc b/src/testradospp.cc
new file mode 100644 (file)
index 0000000..bc7c5f7
--- /dev/null
@@ -0,0 +1,58 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * 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 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#include "include/librados.h"
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <time.h>
+
+int main(int argc, const char **argv) 
+{
+  Rados rados;
+  if (!rados.initialize(0, NULL)) {
+     cerr << "couldn't initialize rados!" << std::endl;
+     exit(1);
+  }
+
+  time_t tm;
+  bufferlist bl, bl2;
+  char buf[128];
+
+  time(&tm);
+  snprintf(buf, 128, "%s", ctime(&tm));
+  bl.append(buf, strlen(buf) + 1);
+
+  object_t oid;
+  memset(&oid, 0, sizeof(oid));
+  oid.ino = 0x2010;
+
+  rados_pool_t pool;
+  int r = rados.open_pool("data", &pool);
+  printf("open pool result = %d, pool = %d\n", r, pool);
+
+  rados.write(pool, oid, 0, bl, bl.length());
+  rados.exec(pool, oid, "test", "foo", bl, bl.length(), bl2, 1024);
+  printf("exec result=%s\n", bl2.c_str());
+  int size = rados.read(pool, oid, 0, bl2, 128);
+
+  rados.close_pool(pool);
+
+  cout << "read result=" << bl2.c_str() << std::endl;
+  cout << "size=" << size << std::endl;
+
+  return 0;
+}
+