From 67baf00dc2facda5a97131cedb9c759fad9d6af1 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 20 May 2009 13:35:50 -0700 Subject: [PATCH] rados: supply a C++ api --- src/Makefile.am | 4 +- src/include/librados.h | 27 ++++++++- src/librados.cc | 123 ++++++++++++++++++++++++++++++++--------- src/testrados.c | 4 +- src/testradospp.cc | 58 +++++++++++++++++++ 5 files changed, 186 insertions(+), 30 deletions(-) create mode 100644 src/testradospp.cc diff --git a/src/Makefile.am b/src/Makefile.am index 7d499eb605726..c06f1a481c063 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/include/librados.h b/src/include/librados.h index 22ed6e44889b1..ffb0535517ef6 100644 --- a/src/include/librados.h +++ b/src/include/librados.h @@ -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 diff --git a/src/librados.cc b/src/librados.cc index e0a2092698771..ffbdce0832d5f 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -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 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; } diff --git a/src/testrados.c b/src/testrados.c index 87462a92389f6..44b3b5fc98a4f 100644 --- a/src/testrados.c +++ b/src/testrados.c @@ -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 index 0000000000000..bc7c5f7c34e9c --- /dev/null +++ b/src/testradospp.cc @@ -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 + * + * 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 + +#include +#include + +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; +} + -- 2.39.5