]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: C++ API rework
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 24 Feb 2011 16:14:20 +0000 (08:14 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Fri, 25 Feb 2011 16:06:58 +0000 (08:06 -0800)
Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
15 files changed:
src/include/rados/librados.h
src/include/rados/librados.hpp
src/include/rbd/librbd.hpp
src/librados.cc
src/librbd.cc
src/osdc/rados_bencher.h
src/rados.cc
src/radosacl.cc
src/rbd.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/test/osd/RadosModel.h
src/testlibrbd.c
src/testrados.c
src/testradospp.cc

index d220cad2747f609558a79d9e1df5cb6140f55016..2263352051ae6610c851ab3e32c672483b6ae563 100644 (file)
@@ -57,7 +57,7 @@ int rados_create(rados_t *cluster, const char * const id);
 int rados_connect(rados_t cluster);
 
 /* destroy the cluster instance */
-void rados_destroy(rados_t cluster);
+void rados_shutdown(rados_t cluster);
 
 /* Config
  *
@@ -169,7 +169,7 @@ int rados_aio_write(rados_pool_t pool, const char *oid,
                    const char *buf, size_t len, off_t off);
 int rados_aio_write_full(rados_pool_t pool, const char *oid,
                         rados_completion_t completion,
-                        const char *buf, size_t len, off_t off);
+                        const char *buf, size_t len);
 int rados_aio_read(rados_pool_t pool, const char *oid,
                   rados_completion_t completion,
                   char *buf, size_t len, off_t off);
index 33a6d9197c93c8718a4a738ab25356463c3076d0..a1edb9f17b4bf8349b57c5d266852a2cd1c314b2 100644 (file)
 
 class RadosClient;
 class Context;
+class AioCompletionImpl;
+class PoolCtx;
 
-namespace librados {
-
+namespace librados
+{
+  class Pool;
+  class PoolHandle;
   using ceph::bufferlist;
 
   typedef void *list_ctx_t;
@@ -47,92 +51,30 @@ namespace librados {
     std::vector<snap_t> snaps;
   };
 
+  class ObjectIterator : public std::iterator <std::forward_iterator_tag, std::string> {
+  public:
+    static const ObjectIterator __EndObjectIterator;
+    ObjectIterator(rados_list_ctx_t ctx_);
+    ~ObjectIterator();
+    bool operator==(const ObjectIterator& rhs) const;
+    bool operator!=(const ObjectIterator& rhs) const;
+    const std::string& operator*() const;
+    ObjectIterator &operator++(); // Preincrement
+    ObjectIterator operator++(int); // Postincrement
+  private:
+    void get_next();
+    rados_list_ctx_t ctx;
+    bufferlist *bl;
+    std::string cur_obj;
+  };
 
-
-class Rados
-{
-  RadosClient *client;
-public:
-  Rados();
-  Rados(pool_t pool);
-  ~Rados();
-
-  /* We don't allow assignment or copying */
-  Rados(const Rados& rhs);
-  const Rados& operator=(const Rados& rhs);
-
-  int initialize(int argc, const char *argv[]);
-  void shutdown();
-
-  void version(int *major, int *minor, int *extra);
-
-  int open_pool(const char *name, pool_t *pool);
-  int close_pool(pool_t pool);
-  int lookup_pool(const char *name);
-
-  void set_snap_read(pool_t pool, snap_t seq);
-  int set_snap_write_context(pool_t pool, snap_t seq, std::vector<snap_t>& snaps);
-
-  uint64_t get_last_version(pool_t pool);
-
-  int create(pool_t pool, const std::string& oid, bool exclusive);
-
-  int write(pool_t pool, const std::string& oid, off_t off, bufferlist& bl, size_t len);
-  int write_full(pool_t pool, const std::string& oid, bufferlist& bl);
-  int read(pool_t pool, const std::string& oid, off_t off, bufferlist& bl, size_t len);
-  int remove(pool_t pool, const std::string& oid);
-  int trunc(pool_t pool, const std::string& oid, size_t size);
-  int mapext(pool_t pool, const std::string& o, off_t off, size_t len, std::map<off_t, size_t>& m);
-  int sparse_read(pool_t pool, const std::string& o, off_t off, size_t len, std::map<off_t, size_t>& m, bufferlist& bl);
-  int getxattr(pool_t pool, const std::string& oid, const char *name, bufferlist& bl);
-  int setxattr(pool_t pool, const std::string& oid, const char *name, bufferlist& bl);
-  int rmxattr(pool_t pool, const std::string& oid, const char *name);
-  int getxattrs(pool_t pool, const std::string& oid, std::map<std::string, bufferlist>& attrset);
-  int stat(pool_t pool, const std::string& oid, uint64_t *psize, time_t *pmtime);
-
-  int tmap_update(pool_t pool, const std::string& oid, bufferlist& cmdbl);
-  
-  int exec(pool_t pool, const std::string& oid, const char *cls, const char *method,
-          bufferlist& inbl, bufferlist& outbl);
-
-  /* listing objects */
-  struct ListCtx {
-    void *ctx;
-    bufferlist *extra_info;
-    ListCtx() : ctx(NULL), extra_info(NULL) {}
+  class WatchCtx {
+  public:
+    virtual void notify(uint8_t opcode, uint64_t ver) = 0;
   };
-  int objects_list_open(pool_t pool, Rados::ListCtx *ctx);
-  int objects_list_more(Rados::ListCtx& ctx, int max, std::list<std::string>& entries);
-  void objects_list_close(Rados::ListCtx& ctx);
-  void list_filter(Rados::ListCtx& ctx, bufferlist& filter, bufferlist *extra_info);
-
-  int pool_list(std::list<std::string>& v);
-  int pool_get_stats(std::list<std::string>& v,
-                    std::map<std::string,pool_stat_t>& stats);
-  int fs_get_stats(statfs_t& result);
-
-  int create_pool(const char *name, uint64_t auid=0, __u8 crush_rule=0);
-  int delete_pool(pool_t pool);
-  int change_pool_auid(pool_t pool, uint64_t auid);
-
-  int snap_create(pool_t pool, const char *snapname);
-  int selfmanaged_snap_create(pool_t pool, uint64_t *snapid);
-  int snap_remove(pool_t pool, const char *snapname);
-  int snap_rollback_object(pool_t pool, const std::string& oid,
-                          const char *snapname);
-  int selfmanaged_snap_remove(pool_t pool, uint64_t snapid);
-  int selfmanaged_snap_rollback_object(pool_t pool,
-                                const std::string& oid,
-                                SnapContext& snapc, uint64_t snapid);
-  int snap_list(pool_t pool, std::vector<snap_t> *snaps);
-  int snap_get_name(pool_t pool, snap_t snap, std::string *name);
-  int snap_get_stamp(pool_t pool, snap_t snap, time_t *t);
-  int snap_lookup(pool_t, const char *snapname, snap_t *snapid);
-
-  // -- aio --
+
   struct AioCompletion {
-    void *pc;
-    AioCompletion(void *_pc) : pc(_pc) {}
+    AioCompletion(AioCompletionImpl *pc_) : pc(pc_) {}
     int set_complete_callback(void *cb_arg, callback_t cb);
     int set_safe_callback(void *cb_arg, callback_t cb);
     int wait_for_complete();
@@ -142,34 +84,165 @@ public:
     int get_return_value();
     int get_version();
     void release();
+    AioCompletionImpl *pc;
   };
 
-  int aio_read(pool_t pool, const std::string& oid, off_t off, bufferlist *pbl, size_t len,
-              AioCompletion *c);
-  int aio_sparse_read(pool_t pool, const std::string& oid, off_t off,
-                     std::map<off_t,size_t> *m, bufferlist *data_bl, size_t len,
-                     AioCompletion *c);
-  int aio_write(pool_t pool, const std::string& oid, off_t off, const bufferlist& bl, size_t len,
-               AioCompletion *c);
-
-  AioCompletion *aio_create_completion();
-  AioCompletion *aio_create_completion(void *cb_arg, callback_t cb_complete, callback_t cb_safe);
-
-  class WatchCtx {
+  /* PoolHandle : Represents our view of a Pool.
+   *
+   * Typical use (error checking omitted):
+   *
+   * PoolHandle *p;
+   * rados.pool_open("my_pool", &pool);
+   * p->stat(&stats);
+   * ... etc ...
+   * delete p; // close our pool handle
+   */
+  class PoolHandle
+  {
   public:
-  virtual void notify(uint8_t opcode, uint64_t ver) = 0;
+    PoolHandle();
+    static void from_rados_pool_t(rados_pool_t p, PoolHandle &pool);
+
+    // Close our pool handle
+    ~PoolHandle();
+    void close();
+
+    // Remove this Pool from the cluster.
+    // If successful, the pool handle will be closed after this call
+    // Returns 0 on success; error code otherwise.
+    int destroy();
+
+    // set pool auid
+    int set_auid(uint64_t auid_);
+
+    // create an object
+    int create(const std::string& oid, bool exclusive);
+
+    int write(const std::string& oid, bufferlist& bl, size_t len, off_t off);
+    int write_full(const std::string& oid, bufferlist& bl);
+    int read(const std::string& oid, bufferlist& bl, size_t len, off_t off);
+    int remove(const std::string& oid);
+    int trunc(const std::string& oid, size_t size);
+    int mapext(const std::string& o, off_t off, size_t len, std::map<off_t, size_t>& m);
+    int sparse_read(const std::string& o, std::map<off_t, size_t>& m, bufferlist& bl, size_t len, off_t off);
+    int getxattr(const std::string& oid, const char *name, bufferlist& bl);
+    int getxattrs(const std::string& oid, std::map<std::string, bufferlist>& attrset);
+    int setxattr(const std::string& oid, const char *name, bufferlist& bl);
+    int rmxattr(const std::string& oid, const char *name);
+    int stat(const std::string& oid, uint64_t *psize, time_t *pmtime);
+    int exec(const std::string& oid, const char *cls, const char *method,
+            bufferlist& inbl, bufferlist& outbl);
+    int tmap_update(const std::string& oid, bufferlist& cmdbl);
+
+    void snap_set_read(snap_t seq);
+    int selfmanaged_snap_set_write_ctx(snap_t seq, std::vector<snap_t>& snaps);
+
+    // Create a snapshot with a given name
+    int snap_create(const char *snapname);
+
+    // Look up a snapshot by name.
+    // Returns 0 on success; error code otherwise
+    int snap_lookup(const char *snapname, snap_t *snap);
+
+    // Gets a timestamp for a snap
+    int snap_get_stamp(snap_t snapid, time_t *t);
+
+    // Gets the name of a snap
+    int snap_get_name(snap_t snapid, std::string *s);
+
+    // Remove a snapshot from this pool
+    int snap_remove(const char *snapname);
+
+    int snap_list(std::vector<snap_t> *snaps);
+
+    int rollback(const std::string& oid, const char *snapname);
+
+    int selfmanaged_snap_create(uint64_t *snapid);
+
+    int selfmanaged_snap_remove(uint64_t snapid);
+
+    // !!!REMOVE THIS!!!
+    int selfmanaged_snap_rollback(const std::string& oid, SnapContext& snapc,
+                                  uint64_t snapid);
+
+    ObjectIterator objects_begin();
+    const ObjectIterator& objects_end() const;
+
+    uint64_t get_last_version();
+
+    int aio_read(const std::string& oid, AioCompletion *c,
+                bufferlist *pbl, size_t len, off_t off);
+    int aio_sparse_read(const std::string& oid, AioCompletion *c,
+                       std::map<off_t,size_t> *m, bufferlist *data_bl,
+                       size_t len, off_t off);
+    int aio_write(const std::string& oid, AioCompletion *c, const bufferlist& bl,
+                 size_t len, off_t off);
+    int aio_write_full(const std::string& oid, AioCompletion *c, const bufferlist& bl);
+
+    // watch/notify
+    int watch(const std::string& o, uint64_t ver, uint64_t *handle,
+             librados::WatchCtx *ctx);
+    int unwatch(const std::string& o, uint64_t handle);
+    int notify(const std::string& o, uint64_t ver);
+    void set_notify_timeout(uint32_t timeout);
+
+    // assert version for next sync operations
+    void set_assert_version(uint64_t ver);
+
+    const std::string& get_name() const;
+  private:
+    /* You can only get Pool instances from Rados */
+    PoolHandle(PoolCtx *pool_ctx_);
+
+    friend class Rados; // Only Rados can use our private constructor to create Pools.
+
+    /* We don't allow assignment or copying */
+    PoolHandle(const PoolHandle& rhs);
+    const PoolHandle& operator=(const PoolHandle& rhs);
+    PoolCtx *pool_ctx;
+    std::string name;
   };
 
-  // watch/notify
-  int watch(pool_t pool, const std::string& o, uint64_t ver, uint64_t *handle, librados::Rados::WatchCtx *ctx);
-  int unwatch(pool_t pool, const std::string& o, uint64_t handle);
-  int notify(pool_t pool, const std::string& o, uint64_t ver);
-  void set_notify_timeout(pool_t pool, uint32_t timeout);
-
-  /* assert version for next sync operations */
-  void set_assert_version(pool_t pool, uint64_t ver);
-};
-
+  class Rados
+  {
+  public:
+    static void version(int *major, int *minor, int *extra);
+
+    Rados();
+    ~Rados();
+
+    int init(const char * const id);
+    int connect();
+    void shutdown();
+    int conf_read_file(const char * const path) const;
+    int conf_set(const char *option, const char *value);
+    void reopen_log();
+    int conf_get(const char *option, std::string &val);
+
+    int pool_create(const char *name);
+    int pool_create(const char *name, uint64_t auid);
+    int pool_create(const char *name, uint64_t auid, __u8 crush_rule);
+    int pool_open(const char *name, PoolHandle &pool);
+    int pool_lookup(const char *name);
+
+    /* listing objects */
+    int pool_list(std::list<std::string>& v);
+    int get_pool_stats(std::list<std::string>& v,
+                      std::map<std::string,pool_stat_t>& stats);
+    int get_fs_stats(statfs_t& result);
+
+    // -- aio --
+    static AioCompletion *aio_create_completion();
+    static AioCompletion *aio_create_completion(void *cb_arg, callback_t cb_complete,
+                                               callback_t cb_safe);
+
+    friend std::ostream& operator<<(std::ostream &oss, const Rados& r);
+  private:
+    // We don't allow assignment or copying
+    Rados(const Rados& rhs);
+    const Rados& operator=(const Rados& rhs);
+    RadosClient *client;
+  };
 }
 
 #endif
index 2d8dcafb3a3193aa1c058006e2124c3a957239c6..7fb4ac279ff91ca4d35a10a43db2df762f56c037 100644 (file)
@@ -26,7 +26,7 @@
 
 namespace librbd {
 
-  using librados::pool_t;
+  using librados::PoolHandle;
 
   class RBDClient;
   typedef void *image_t;
@@ -61,13 +61,13 @@ public:
 
   void version(int *major, int *minor, int *extra);
 
-  int list(pool_t pool, std::vector<std::string>& names);
-  int create(pool_t pool, const char *name, size_t size, int *order);
-  int remove(pool_t pool, const char *name);
-  int copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *destname);
-  int rename(pool_t src_pool, const char *srcname, const char *destname);
+  int list(PoolHandle& pool, std::vector<std::string>& names);
+  int create(PoolHandle& pool, const char *name, size_t size, int *order);
+  int remove(PoolHandle& pool, const char *name);
+  int copy(PoolHandle& src_pool, const char *srcname, PoolHandle& dest_pool, const char *destname);
+  int rename(PoolHandle& src_pool, const char *srcname, const char *destname);
 
-  int open(pool_t pool, const char *name, image_t *image, const char *snap_name = NULL);
+  int open(PoolHandle& pool, const char *name, image_t *image, const char *snap_name = NULL);
   int close(image_t image);
   int resize(image_t image, size_t size);
   int stat(image_t image, image_info_t& info, size_t infosize);
index a819ebb0b3ccee8f8875a1027d10d4f96eb007f9..f3acc80a5240617a8be2ba13c63f71b49e4bf981 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 <sys/types.h>
@@ -50,6 +50,158 @@ using namespace std;
 #define dout_prefix *_dout << "librados: "
 
 
+/*
+ * Structure of this file
+ *
+ * RadosClient and the related classes are the internal implementation of librados.
+ * Above that layer sits the C API, found in include/rados/librados.h, and
+ * the C++ API, found in include/rados/librados.hpp
+ *
+ * The C++ API sometimes implements things in terms of the C API.
+ * Both the C++ and C API rely on RadosClient.
+ *
+ * Visually:
+ * +--------------------------------------+
+ * |             C++ API                  |
+ * +--------------------+                 |
+ * |       C API        |                 |
+ * +--------------------+-----------------+
+ * |          RadosClient                 |
+ * +--------------------------------------+
+ */
+
+///////////////////////////// RadosClient //////////////////////////////
+struct PoolCtx {
+  RadosClient *client;
+  int poolid;
+  string name;
+  snapid_t snap_seq;
+  SnapContext snapc;
+  uint64_t assert_ver;
+  eversion_t last_objver;
+  uint32_t notify_timeout;
+
+  PoolCtx(RadosClient *c, int pid, const char *n, snapid_t s = CEPH_NOSNAP) :
+    client(c), poolid(pid), name(n), snap_seq(s), assert_ver(0),
+    notify_timeout(g_conf.client_notify_timeout) {}
+
+  void set_snap_read(snapid_t s) {
+    if (!s)
+      s = CEPH_NOSNAP;
+    snap_seq = s;
+  }
+
+  int set_snap_write_context(snapid_t seq, vector<snapid_t>& snaps) {
+    SnapContext n;
+    n.seq = seq;
+    n.snaps = snaps;
+    if (!n.is_valid())
+      return -EINVAL;
+    snapc = n;
+    return 0;
+  }
+};
+
+
+struct AioCompletionImpl {
+  Mutex lock;
+  Cond cond;
+  int ref, rval;
+  bool released;
+  bool ack, safe;
+  eversion_t objver;
+
+  rados_callback_t callback_complete, callback_safe;
+  void *callback_arg;
+
+  // for read
+  bufferlist bl, *pbl;
+  char *buf;
+  unsigned maxlen;
+
+  AioCompletionImpl() : lock("AioCompletionImpl lock"),
+                   ref(1), rval(0), released(false), ack(false), safe(false),
+                   callback_complete(0), callback_safe(0), callback_arg(0),
+                   pbl(0), buf(0), maxlen(0) { }
+
+  int set_complete_callback(void *cb_arg, rados_callback_t cb) {
+    lock.Lock();
+    callback_complete = cb;
+    callback_arg = cb_arg;
+    lock.Unlock();
+    return 0;
+  }
+  int set_safe_callback(void *cb_arg, rados_callback_t cb) {
+    lock.Lock();
+    callback_safe = cb;
+    callback_arg = cb_arg;
+    lock.Unlock();
+    return 0;
+  }
+  int wait_for_complete() {
+    lock.Lock();
+    while (!ack)
+      cond.Wait(lock);
+    lock.Unlock();
+    return 0;
+  }
+  int wait_for_safe() {
+    lock.Lock();
+    while (!safe)
+      cond.Wait(lock);
+    lock.Unlock();
+    return 0;
+  }
+  int is_complete() {
+    lock.Lock();
+    int r = ack;
+    lock.Unlock();
+    return r;
+  }
+  int is_safe() {
+    lock.Lock();
+    int r = safe;
+    lock.Unlock();
+    return r;
+  }
+  int get_return_value() {
+    lock.Lock();
+    int r = rval;
+    lock.Unlock();
+    return r;
+  }
+  uint64_t get_version() {
+    lock.Lock();
+    eversion_t v = objver;
+    lock.Unlock();
+    return v.version;
+  }
+
+  void get() {
+    lock.Lock();
+    assert(ref > 0);
+    ref++;
+    lock.Unlock();
+  }
+  void release() {
+    lock.Lock();
+    assert(!released);
+    released = true;
+    put_unlock();
+  }
+  void put() {
+    lock.Lock();
+    put_unlock();
+  }
+  void put_unlock() {
+    assert(ref > 0);
+    int n = --ref;
+    lock.Unlock();
+    if (!n)
+      delete this;
+  }
+};
+
 class RadosClient : public Dispatcher
 {
   OSDMap osdmap;
@@ -88,37 +240,6 @@ public:
   int connect();
   void shutdown();
 
-  struct PoolCtx {
-    RadosClient *client;
-    int poolid;
-    string name;
-    snapid_t snap_seq;
-    SnapContext snapc;
-    uint64_t assert_ver;
-    eversion_t last_objver;
-    uint32_t notify_timeout;
-
-    PoolCtx(RadosClient *c, int pid, const char *n, snapid_t s = CEPH_NOSNAP) :
-      client(c), poolid(pid), name(n), snap_seq(s), assert_ver(0),
-      notify_timeout(g_conf.client_notify_timeout) {}
-
-    void set_snap_read(snapid_t s) {
-      if (!s)
-       s = CEPH_NOSNAP;
-      snap_seq = s;
-    }
-
-    int set_snap_write_context(snapid_t seq, vector<snapid_t>& snaps) {
-      SnapContext n;
-      n.seq = seq;
-      n.snaps = snaps;
-      if (!n.is_valid())
-       return -EINVAL;
-      snapc = n;
-      return 0;
-    }
-  };
-
   struct ListCtx {
     PoolCtx *ctx;
     Objecter::ListContext *lc;
@@ -137,6 +258,11 @@ public:
     return ret;
   }
 
+  const char *get_pool_name(int poolid_)
+  {
+    return osdmap.get_pool_name(poolid_);
+  }
+
   // snaps
   int snap_list(PoolCtx *pool, vector<uint64_t> *snaps);
   int snap_lookup(PoolCtx *pool, const char *name, uint64_t *snapid);
@@ -145,19 +271,19 @@ public:
   int snap_create(rados_pool_t pool, const char* snapname);
   int selfmanaged_snap_create(rados_pool_t pool, uint64_t *snapid);
   int snap_remove(rados_pool_t pool, const char* snapname);
-  int snap_rollback_object(rados_pool_t pool, const object_t& oid,
-                   const char* snapname);
+  int rollback(rados_pool_t pool_, const object_t& oid, const char *snapName);
   int selfmanaged_snap_remove(rados_pool_t pool, uint64_t snapid);
   int selfmanaged_snap_rollback_object(rados_pool_t pool, const object_t& oid,
                                        SnapContext& snapc, uint64_t snapid);
 
   // io
   int create(PoolCtx& pool, const object_t& oid, bool exclusive);
-  int write(PoolCtx& pool, const object_t& oid, off_t off, bufferlist& bl, size_t len);
+  int write(PoolCtx& pool, const object_t& oid, bufferlist& bl, size_t len, off_t off);
   int write_full(PoolCtx& pool, const object_t& oid, bufferlist& bl);
-  int read(PoolCtx& pool, const object_t& oid, off_t off, bufferlist& bl, size_t len);
+  int read(PoolCtx& pool, const object_t& oid, bufferlist& bl, size_t len, off_t off);
   int mapext(PoolCtx& pool, const object_t& oid, off_t off, size_t len, std::map<off_t,size_t>& m);
-  int sparse_read(PoolCtx& pool, const object_t& oid, off_t off, size_t len, std::map<off_t,size_t>& m, bufferlist& bl);
+  int sparse_read(PoolCtx& pool, const object_t& oid, std::map<off_t,size_t>& m, bufferlist& bl,
+                 size_t len, off_t off);
   int remove(PoolCtx& pool, const object_t& oid);
   int stat(PoolCtx& pool, const object_t& oid, uint64_t *psize, time_t *pmtime);
   int trunc(PoolCtx& pool, const object_t& oid, size_t size);
@@ -170,118 +296,18 @@ public:
   int getxattrs(PoolCtx& pool, const object_t& oid, map<string, bufferlist>& attrset);
   int rmxattr(PoolCtx& pool, const object_t& oid, const char *name);
 
-  int list_pools(std::list<string>& ls);
+  int pool_list(std::list<string>& ls);
   int get_pool_stats(std::list<string>& ls, map<string,pool_stat_t>& result);
   int get_fs_stats(ceph_statfs& result);
 
-  int create_pool(string& name, unsigned long long auid=0, __u8 crush_rule=0);
-  int delete_pool(rados_pool_t pool);
-  int change_pool_auid(rados_pool_t pool, unsigned long long auid);
+  int pool_create(string& name, unsigned long long auid=0, __u8 crush_rule=0);
+  int pool_delete(rados_pool_t pool);
+  int pool_change_auid(rados_pool_t pool, unsigned long long auid);
 
   int list(Objecter::ListContext *context, int max_entries);
 
-  // --- aio ---
-  struct AioCompletion {
-    Mutex lock;
-    Cond cond;
-    int ref, rval;
-    bool released;
-    bool ack, safe;
-    eversion_t objver;
-
-    rados_callback_t callback_complete, callback_safe;
-    void *callback_arg;
-
-    // for read
-    bufferlist bl, *pbl;
-    char *buf;
-    unsigned maxlen;
-
-    AioCompletion() : lock("RadosClient::AioCompletion::lock"),
-                     ref(1), rval(0), released(false), ack(false), safe(false), 
-                     callback_complete(0), callback_safe(0), callback_arg(0),
-                     pbl(0), buf(0), maxlen(0) { }
-
-    int set_complete_callback(void *cb_arg, rados_callback_t cb) {
-      lock.Lock();
-      callback_complete = cb;
-      callback_arg = cb_arg;
-      lock.Unlock();
-      return 0;
-    }
-    int set_safe_callback(void *cb_arg, rados_callback_t cb) {
-      lock.Lock();
-      callback_safe = cb;
-      callback_arg = cb_arg;
-      lock.Unlock();
-      return 0;
-    }
-    int wait_for_complete() {
-      lock.Lock();
-      while (!ack)
-       cond.Wait(lock);
-      lock.Unlock();
-      return 0;
-    }
-    int wait_for_safe() {
-      lock.Lock();
-      while (!safe)
-       cond.Wait(lock);
-      lock.Unlock();
-      return 0;
-    }
-    int is_complete() {
-      lock.Lock();
-      int r = ack;
-      lock.Unlock();
-      return r;
-    }
-    int is_safe() {
-      lock.Lock();
-      int r = safe;
-      lock.Unlock();
-      return r;
-    }
-    int get_return_value() {
-      lock.Lock();
-      int r = rval;
-      lock.Unlock();
-      return r;
-    }
-    uint64_t get_version() {
-      lock.Lock();
-      eversion_t v = objver;
-      lock.Unlock();
-      return v.version;
-    }
-
-    void get() {
-      lock.Lock();
-      assert(ref > 0);
-      ref++;
-      lock.Unlock();
-    }
-    void release() {
-      lock.Lock();
-      assert(!released);
-      released = true;
-      put_unlock();
-    }
-    void put() {
-      lock.Lock();
-      put_unlock();
-    }
-    void put_unlock() {
-      assert(ref > 0);
-      int n = --ref;
-      lock.Unlock();
-      if (!n)
-       delete this;
-    }
-  };
-
   struct C_aio_Ack : public Context {
-    AioCompletion *c;
+    AioCompletionImpl *c;
     void finish(int r) {
       c->lock.Lock();
       c->rval = r;
@@ -307,16 +333,16 @@ public:
 
       c->put_unlock();
     }
-    C_aio_Ack(AioCompletion *_c) : c(_c) {
+    C_aio_Ack(AioCompletionImpl *_c) : c(_c) {
       c->get();
     }
   };
-  
+
   struct C_aio_sparse_read_Ack : public Context {
-    AioCompletion *c;
+    AioCompletionImpl *c;
     bufferlist *data_bl;
     std::map<off_t,size_t> *m;
-    
+
     void finish(int r) {
       c->lock.Lock();
       c->rval = r;
@@ -339,13 +365,13 @@ public:
 
       c->put_unlock();
     }
-    C_aio_sparse_read_Ack(AioCompletion *_c) : c(_c) {
+    C_aio_sparse_read_Ack(AioCompletionImpl *_c) : c(_c) {
       c->get();
     }
   };
 
   struct C_aio_Safe : public Context {
-    AioCompletion *c;
+    AioCompletionImpl *c;
     void finish(int r) {
       c->lock.Lock();
       if (!c->ack) {
@@ -365,31 +391,28 @@ public:
 
       c->put_unlock();
     }
-    C_aio_Safe(AioCompletion *_c) : c(_c) {
+    C_aio_Safe(AioCompletionImpl *_c) : c(_c) {
       c->get();
     }
   };
 
-  int aio_read(PoolCtx& pool, object_t oid, off_t off, bufferlist *pbl, size_t len,
-              AioCompletion *c);
-  int aio_read(PoolCtx& pool, object_t oid, off_t off, char *buf, size_t len,
-              AioCompletion *c);
-
-  int aio_sparse_read(PoolCtx& pool, const object_t oid, off_t off,
-                     std::map<off_t,size_t> *m, bufferlist *data_bl, size_t len,
-                     AioCompletion *c);
-
-  int aio_write(PoolCtx& pool, object_t oid, off_t off, const bufferlist& bl, size_t len,
-               AioCompletion *c);
-
-  int aio_write_full(PoolCtx& pool, object_t oid, const bufferlist& bl,
-                   AioCompletion *c);
-
-  static AioCompletion *aio_create_completion() {
-    return new AioCompletion;
+  int aio_read(PoolCtx& pool, const object_t oid, AioCompletionImpl *c,
+                         bufferlist *pbl, size_t len, off_t off);
+  int aio_read(PoolCtx& pool, object_t oid, AioCompletionImpl *c,
+              char *buf, size_t len, off_t off);
+  int aio_sparse_read(PoolCtx& pool, const object_t oid,
+                   AioCompletionImpl *c, std::map<off_t,size_t> *m,
+                   bufferlist *data_bl, size_t len, off_t off);
+  int aio_write(PoolCtx& pool, const object_t &oid, AioCompletionImpl *c,
+               const bufferlist& bl, size_t len, off_t off);
+  int aio_write_full(PoolCtx& pool, const object_t &oid, AioCompletionImpl *c,
+                    const bufferlist& bl);
+
+  static AioCompletionImpl *aio_create_completion() {
+    return new AioCompletionImpl;
   }
-  static AioCompletion *aio_create_completion(void *cb_arg, rados_callback_t cb_complete, rados_callback_t cb_safe) {
-    AioCompletion *c = new AioCompletion;
+  static AioCompletionImpl *aio_create_completion(void *cb_arg, rados_callback_t cb_complete, rados_callback_t cb_safe) {
+    AioCompletionImpl *c = new AioCompletionImpl;
     if (cb_complete)
       c->set_complete_callback(cb_arg, cb_complete);
     if (cb_safe)
@@ -397,18 +420,17 @@ public:
     return c;
   }
 
-
   // watch/notify
   struct WatchContext {
     PoolCtx pool_ctx;
-    const object_t oid; 
+    const object_t oid;
     uint64_t cookie;
     uint64_t ver;
-    librados::Rados::WatchCtx *ctx;
+    librados::WatchCtx *ctx;
     ObjectOperation *op;
     uint64_t linger_id;
 
-    WatchContext(PoolCtx& _pc, const object_t& _oc, librados::Rados::WatchCtx *_ctx,
+    WatchContext(PoolCtx& _pc, const object_t& _oc, librados::WatchCtx *_ctx,
                  ObjectOperation *_op) : pool_ctx(_pc), oid(_oc), ctx(_ctx), op(_op), linger_id(0) {}
     ~WatchContext() {
     }
@@ -420,7 +442,7 @@ public:
     }
   };
 
-  struct C_NotifyComplete : public librados::Rados::WatchCtx {
+  struct C_NotifyComplete : public librados::WatchCtx {
     Mutex *lock;
     Cond *cond;
     bool *done;
@@ -438,12 +460,12 @@ public:
 
   uint64_t max_watch_cookie;
   map<uint64_t, WatchContext *> watchers;
+
   void set_sync_op_version(PoolCtx& pool, eversion_t& ver) {
       pool.last_objver = ver;
   }
 
-  void register_watcher(PoolCtx& pool, const object_t& oid, librados::Rados::WatchCtx *ctx,
+  void register_watcher(PoolCtx& pool, const object_t& oid, librados::WatchCtx *ctx,
                        ObjectOperation *op, uint64_t *cookie, WatchContext **pwc = NULL) {
     assert(lock.is_locked());
     WatchContext *wc = new WatchContext(pool, oid, ctx, op);
@@ -467,7 +489,7 @@ public:
 
   void watch_notify(MWatchNotify *m);
 
-  int watch(PoolCtx& pool, const object_t& oid, uint64_t ver, uint64_t *cookie, librados::Rados::WatchCtx *ctx);
+  int watch(PoolCtx& pool, const object_t& oid, uint64_t ver, uint64_t *cookie, librados::WatchCtx *ctx);
   int unwatch(PoolCtx& pool, const object_t& oid, uint64_t cookie);
   int notify(PoolCtx& pool, const object_t& oid, uint64_t ver);
   int _notify_ack(PoolCtx& pool, const object_t& oid, uint64_t notify_id, uint64_t ver);
@@ -506,7 +528,7 @@ int RadosClient::connect()
   objecter->set_balanced_budget();
 
   monclient.set_messenger(messenger);
-  
+
   messenger->add_dispatcher_head(this);
 
   messenger->start(1);
@@ -627,10 +649,10 @@ bool RadosClient::_dispatch(Message *m)
   return true;
 }
 
-int RadosClient::list_pools(std::list<string>& v)
+int RadosClient::pool_list(std::list<std::string>& v)
 {
   Mutex::Locker l(lock);
-  for (map<int,pg_pool_t>::const_iterator p = osdmap.get_pools().begin(); 
+  for (map<int,pg_pool_t>::const_iterator p = osdmap.get_pools().begin();
        p != osdmap.get_pools().end();
        p++)
     v.push_back(osdmap.get_pool_name(p->first));
@@ -646,7 +668,7 @@ int RadosClient::get_pool_stats(std::list<string>& pools, map<string,pool_stat_t
   lock.Lock();
   objecter->get_pool_stats(pools, &result, new C_SafeCond(&mylock, &cond, &done));
   lock.Unlock();
-  
+
   mylock.Lock();
   while (!done)
     cond.Wait(mylock);
@@ -674,7 +696,7 @@ int RadosClient::get_fs_stats(ceph_statfs& stats)
 
 // SNAPS
 
-int RadosClient::snap_create( rados_pool_t pool, const char *snapName)
+int RadosClient::snap_create(rados_pool_t pool, const char *snapName)
 {
   int reply;
   int poolID = ((PoolCtx *)pool)->poolid;
@@ -763,8 +785,8 @@ int RadosClient::selfmanaged_snap_rollback_object(rados_pool_t pool,
   return reply;
 }
 
-int RadosClient::snap_rollback_object(rados_pool_t pool_,
-                                     const object_t& oid, const char *snapName)
+int RadosClient::rollback(rados_pool_t pool_, const object_t& oid,
+                         const char *snapName)
 {
   PoolCtx* pool = (PoolCtx *) pool_;
   string sName(snapName);
@@ -805,7 +827,7 @@ int RadosClient::selfmanaged_snap_remove(rados_pool_t pool, uint64_t snapid)
   return (int)reply;
 }
 
-int RadosClient::create_pool(string& name, unsigned long long auid,
+int RadosClient::pool_create(string& name, unsigned long long auid,
                             __u8 crush_rule)
 {
   int reply;
@@ -826,13 +848,13 @@ int RadosClient::create_pool(string& name, unsigned long long auid,
   return reply;
 }
 
-int RadosClient::delete_pool(rados_pool_t pool)
+int RadosClient::pool_delete(rados_pool_t pool)
 {
   int reply;
 
   int poolID = ((PoolCtx *)pool)->poolid;
 
-  Mutex mylock("RadosClient::delete_pool::mylock");
+  Mutex mylock("RadosClient::pool_delete::mylock");
   Cond cond;
   bool done;
   lock.Lock();
@@ -852,13 +874,13 @@ int RadosClient::delete_pool(rados_pool_t pool)
  * auid: the auid you wish the pool to have.
  * Returns: 0 on success, or -ERROR# on failure.
  */
-int RadosClient::change_pool_auid(rados_pool_t pool, unsigned long long auid)
+int RadosClient::pool_change_auid(rados_pool_t pool, unsigned long long auid)
 {
   int reply;
 
   int poolID = ((PoolCtx *)pool)->poolid;
 
-  Mutex mylock("RadosClient::change_pool_auid::mylock");
+  Mutex mylock("RadosClient::pool_change_auid::mylock");
   Cond cond;
   bool done;
   lock.Lock();
@@ -982,7 +1004,8 @@ int RadosClient::create(PoolCtx& pool, const object_t& oid, bool exclusive)
   return r;
 }
 
-int RadosClient::write(PoolCtx& pool, const object_t& oid, off_t off, bufferlist& bl, size_t len)
+int RadosClient::write(PoolCtx& pool, const object_t& oid,
+                      bufferlist& bl, size_t len, off_t off)
 {
   utime_t ut = g_clock.now();
 
@@ -1065,10 +1088,10 @@ int RadosClient::write_full(PoolCtx& pool, const object_t& oid, bufferlist& bl)
   return r;
 }
 
-int RadosClient::aio_read(PoolCtx& pool, const object_t oid, off_t off, bufferlist *pbl, size_t len,
-                         AioCompletion *c)
+int RadosClient::aio_read(PoolCtx& pool, const object_t oid, AioCompletionImpl *c,
+                         bufferlist *pbl, size_t len, off_t off)
 {
+
   Context *onack = new C_aio_Ack(c);
   eversion_t ver;
 
@@ -1082,8 +1105,8 @@ int RadosClient::aio_read(PoolCtx& pool, const object_t oid, off_t off, bufferli
   return 0;
 }
 
-int RadosClient::aio_read(PoolCtx& pool, const object_t oid, off_t off, char *buf, size_t len,
-                         AioCompletion *c)
+int RadosClient::aio_read(PoolCtx& pool, const object_t oid, AioCompletionImpl *c,
+                         char *buf, size_t len, off_t off)
 {
   Context *onack = new C_aio_Ack(c);
 
@@ -1099,11 +1122,11 @@ int RadosClient::aio_read(PoolCtx& pool, const object_t oid, off_t off, char *bu
   return 0;
 }
 
-int RadosClient::aio_sparse_read(PoolCtx& pool, const object_t oid, off_t off,
-                         std::map<off_t,size_t> *m, bufferlist *data_bl, size_t len,
-                         AioCompletion *c)
+int RadosClient::aio_sparse_read(PoolCtx& pool, const object_t oid,
+                         AioCompletionImpl *c, std::map<off_t,size_t> *m,
+                         bufferlist *data_bl, size_t len, off_t off)
 {
+
   C_aio_sparse_read_Ack *onack = new C_aio_sparse_read_Ack(c);
   onack->m = m;
   onack->data_bl = data_bl;
@@ -1119,8 +1142,8 @@ int RadosClient::aio_sparse_read(PoolCtx& pool, const object_t oid, off_t off,
   return 0;
 }
 
-int RadosClient::aio_write(PoolCtx& pool, const object_t oid, off_t off, const bufferlist& bl, size_t len,
-                          AioCompletion *c)
+int RadosClient::aio_write(PoolCtx& pool, const object_t &oid, AioCompletionImpl *c,
+                          const bufferlist& bl, size_t len, off_t off)
 {
   SnapContext snapc;
   utime_t ut = g_clock.now();
@@ -1137,8 +1160,8 @@ int RadosClient::aio_write(PoolCtx& pool, const object_t oid, off_t off, const b
   return 0;
 }
 
-int RadosClient::aio_write_full(PoolCtx& pool, const object_t oid, const bufferlist& bl,
-                              AioCompletion *c)
+int RadosClient::aio_write_full(PoolCtx& pool, const object_t &oid,
+               AioCompletionImpl *c, const bufferlist& bl)
 {
   SnapContext snapc;
   utime_t ut = g_clock.now();
@@ -1302,7 +1325,8 @@ int RadosClient::exec(PoolCtx& pool, const object_t& oid, const char *cls, const
   return r;
 }
 
-int RadosClient::read(PoolCtx& pool, const object_t& oid, off_t off, bufferlist& bl, size_t len)
+int RadosClient::read(PoolCtx& pool, const object_t& oid,
+                     bufferlist& bl, size_t len, off_t off)
 {
   SnapContext snapc;
 
@@ -1378,8 +1402,8 @@ int RadosClient::mapext(PoolCtx& pool, const object_t& oid, off_t off, size_t le
   return m.size();
 }
 
-int RadosClient::sparse_read(PoolCtx& pool, const object_t& oid, off_t off, size_t len,
-                             std::map<off_t,size_t>& m, bufferlist& data_bl)
+int RadosClient::sparse_read(PoolCtx& pool, const object_t& oid,
+         std::map<off_t,size_t>& m, bufferlist& data_bl, size_t len, off_t off)
 {
   SnapContext snapc;
   bufferlist bl;
@@ -1642,7 +1666,8 @@ void RadosClient::watch_notify(MWatchNotify *m)
   wc->notify(this, m);
 }
 
-int RadosClient::watch(PoolCtx& pool, const object_t& oid, uint64_t ver, uint64_t *cookie, librados::Rados::WatchCtx *ctx)
+int RadosClient::watch(PoolCtx& pool, const object_t& oid, uint64_t ver,
+                      uint64_t *cookie, librados::WatchCtx *ctx)
 {
   utime_t ut = g_clock.now();
 
@@ -1786,7 +1811,7 @@ int RadosClient::notify(PoolCtx& pool, const object_t& oid, uint64_t ver)
   while (!done_all)
     cond_all.Wait(mylock_all);
   mylock_all.Unlock();
-  
+
   lock.Lock();
   unregister_watcher(cookie);
   lock.Unlock();
@@ -1797,558 +1822,640 @@ int RadosClient::notify(PoolCtx& pool, const object_t& oid, uint64_t ver)
   return r;
 }
 
-namespace librados {
-
-Rados::Rados() : client(NULL)
+///////////////////////////// ObjectIterator /////////////////////////////
+librados::ObjectIterator::
+ObjectIterator(rados_list_ctx_t ctx_)
+: ctx(ctx_)
 {
 }
 
-Rados::Rados(pool_t pool)
+librados::ObjectIterator::
+~ObjectIterator()
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  client = ctx->client;
+  if (ctx) {
+    rados_objects_list_close(ctx);
+    ctx = NULL;
+  }
+}
+
+bool librados::ObjectIterator::
+operator==(const librados::ObjectIterator& rhs) const {
+  return (ctx == rhs.ctx);
 }
 
-Rados::~Rados()
+bool librados::ObjectIterator::
+operator!=(const librados::ObjectIterator& rhs) const {
+  return (ctx != rhs.ctx);
+}
+
+const std::string& librados::ObjectIterator::
+operator*() const {
+  return cur_obj;
+}
+
+librados::ObjectIterator& librados::ObjectIterator::
+operator++()
 {
-  if (client)
-    delete client;
-  client = NULL;
+  get_next();
+  return *this;
 }
 
-int Rados::initialize(int argc, const char *argv[])
+librados::ObjectIterator librados::ObjectIterator::
+operator++(int)
 {
- vector<const char*> args;
+  librados::ObjectIterator ret(*this);
+  get_next();
+  return ret;
+}
 
-  if (argc && argv) {
-    argv_to_vec(argc, argv, args);
-    env_to_vec(args);
+void librados::ObjectIterator::
+get_next()
+{
+  const char *entry;
+  int ret = rados_objects_list_next(ctx, &entry);
+  if (ret == -ENOENT) {
+    rados_objects_list_close(ctx);
+    ctx = NULL;
+    *this = __EndObjectIterator;
+    return;
+  }
+  else if (ret) {
+    ostringstream oss;
+    oss << "rados_objects_list_next returned " << ret;
+    throw std::runtime_error(oss.str());
   }
-  common_init(args, "librados", STARTUP_FLAG_INIT_KEYS);
 
-  return 0;
+  cur_obj = entry;
 }
 
-void Rados::shutdown()
+const librados::ObjectIterator librados::ObjectIterator::
+__EndObjectIterator(NULL);
+
+///////////////////////////// AioCompletion //////////////////////////////
+int librados::AioCompletion::AioCompletion::
+set_complete_callback(void *cb_arg, rados_callback_t cb)
 {
-  if (!client)
-    return;
-  client->shutdown();
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->set_complete_callback(cb_arg, cb);
 }
 
-void Rados::version(int *major, int *minor, int *extra)
+int librados::AioCompletion::AioCompletion::
+set_safe_callback(void *cb_arg, rados_callback_t cb)
 {
-  rados_version(major, minor, extra);
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->set_safe_callback(cb_arg, cb);
 }
 
-int Rados::pool_list(std::list<string>& v)
+int librados::AioCompletion::AioCompletion::
+wait_for_complete()
 {
-  if (!client)
-    return -EINVAL;
-  return client->list_pools(v);
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->wait_for_complete();
 }
 
-int Rados::pool_get_stats(std::list<string>& v, std::map<string,pool_stat_t>& result)
+int librados::AioCompletion::AioCompletion::
+wait_for_safe()
 {
-  if (!client)
-    return -EINVAL;
-  map<string,::pool_stat_t> rawresult;
-  int r = client->get_pool_stats(v, rawresult);
-  for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
-       p != rawresult.end();
-       p++) {
-    pool_stat_t& v = result[p->first];
-    v.num_kb = p->second.num_kb;
-    v.num_bytes = p->second.num_bytes;
-    v.num_objects = p->second.num_objects;
-    v.num_object_clones = p->second.num_object_clones;
-    v.num_object_copies = p->second.num_object_copies;
-    v.num_objects_missing_on_primary = p->second.num_objects_missing_on_primary;
-    v.num_objects_unfound = p->second.num_objects_unfound;
-    v.num_objects_degraded = p->second.num_objects_degraded;
-    v.num_rd = p->second.num_rd;
-    v.num_rd_kb = p->second.num_rd_kb;
-    v.num_wr = p->second.num_wr;
-    v.num_wr_kb = p->second.num_wr_kb;
-  }
-  return r;
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->wait_for_safe();
 }
 
-int Rados::create_pool(const char *name, uint64_t auid, __u8 crush_rule)
+bool librados::AioCompletion::AioCompletion::
+is_complete()
 {
-  string str(name);
-  if (!client)
-    return -EINVAL;
-  return client->create_pool(str, auid, crush_rule);
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->is_complete();
 }
 
-int Rados::delete_pool(rados_pool_t pool)
+bool librados::AioCompletion::AioCompletion::
+is_safe()
 {
-  if (!client) return -EINVAL;
-  return client->delete_pool(pool);
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->is_safe();
 }
 
-int Rados::change_pool_auid(rados_pool_t pool, uint64_t auid)
+int librados::AioCompletion::AioCompletion::
+get_return_value()
 {
-  if (!client) return -EINVAL;
-  return client->change_pool_auid(pool, auid);
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->get_return_value();
 }
 
-int Rados::fs_get_stats(statfs_t& result)
+int librados::AioCompletion::AioCompletion::
+get_version()
 {
-  if (!client)
-    return -EINVAL;
-  ceph_statfs stats;
-  int r = client->get_fs_stats(stats);
-  result.kb = stats.kb;
-  result.kb_used = stats.kb_used;
-  result.kb_avail = stats.kb_avail;
-  result.num_objects = stats.num_objects;
-  return r;
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  return c->get_version();
 }
 
-int Rados::objects_list_open(pool_t pool, Rados::ListCtx *ctx)
+void librados::AioCompletion::AioCompletion::
+release()
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *p = (RadosClient::PoolCtx *)pool;
-  Objecter::ListContext *h = new Objecter::ListContext;
-  h->pool_id = p->poolid;
-  h->pool_snap_seq = p->snap_seq;
-  ctx->ctx = (void *)h;
-  return 0;
+  AioCompletionImpl *c = (AioCompletionImpl *)pc;
+  c->release();
 }
 
-int Rados::objects_list_more(Rados::ListCtx& ctx, int max, std::list<string>& entries)
+///////////////////////////// PoolHandle //////////////////////////////
+librados::PoolHandle::
+PoolHandle() : pool_ctx(NULL)
 {
-  if (!client)
-    return -EINVAL;
+}
 
-  Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
-  h->list.clear();
-  int r = client->list(h, max);
-  while (!h->list.empty()) {
-    entries.push_back(h->list.front().name.c_str());
-    h->list.pop_front();
-  }
-  if (ctx.extra_info)
-    ctx.extra_info->append(h->extra_info);
-  return r;
+void librados::PoolHandle::
+from_rados_pool_t(rados_pool_t p, PoolHandle &pool)
+{
+  PoolCtx *pool_ctx = (PoolCtx*)p;
+
+  pool.pool_ctx = pool_ctx;
+  pool.name = pool_ctx->client->get_pool_name(pool_ctx->poolid);
 }
 
-void Rados::objects_list_close(Rados::ListCtx& ctx)
+librados::PoolHandle::
+~PoolHandle()
 {
-  if (!client)
-    return;
-  Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
-  delete h;
+  close();
 }
 
-void Rados::list_filter(Rados::ListCtx& ctx, bufferlist& filter, bufferlist *extra_info)
+void librados::PoolHandle::
+close()
 {
-  Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
-  h->filter = filter;
-  ctx.extra_info = extra_info;
+  delete pool_ctx;
+  pool_ctx = 0;
 }
 
-uint64_t Rados::get_last_version(rados_pool_t pool)
+int librados::PoolHandle::
+destroy()
 {
-  if (!client)
-    return 0;
+  int ret = pool_ctx->client->pool_delete(pool_ctx);
+  if (ret)
+    return ret;
+  delete pool_ctx;
+  pool_ctx = NULL;
+  return 0;
+}
 
-  eversion_t ver = client->last_version(*(RadosClient::PoolCtx *)pool);
-  return ver.version;
+int librados::PoolHandle::
+set_auid(uint64_t auid_)
+{
+  return pool_ctx->client->pool_change_auid(pool_ctx, auid_);
 }
 
+int librados::PoolHandle::
+create(const std::string& oid, bool exclusive)
+{
+  object_t obj(oid);
+  return pool_ctx->client->create(*pool_ctx, obj, exclusive);
+}
 
-int Rados::create(rados_pool_t pool, const string& o, bool exclusive)
+int librados::PoolHandle::
+write(const std::string& oid, bufferlist& bl, size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->create(*(RadosClient::PoolCtx *)pool, oid, exclusive);
+  object_t obj(oid);
+  return pool_ctx->client->write(*pool_ctx, obj, bl, len, off);
 }
 
-int Rados::write(rados_pool_t pool, const string& o, off_t off, bufferlist& bl, size_t len)
+int librados::PoolHandle::
+write_full(const std::string& oid, bufferlist& bl)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->write(*(RadosClient::PoolCtx *)pool, oid, off, bl, len);
+  object_t obj(oid);
+  return pool_ctx->client->write_full(*pool_ctx, obj, bl);
 }
 
-int Rados::write_full(rados_pool_t pool, const string& o, bufferlist& bl)
+int librados::PoolHandle::
+read(const std::string& oid, bufferlist& bl, size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->write_full(*(RadosClient::PoolCtx *)pool, oid, bl);
+  object_t obj(oid);
+  return pool_ctx->client->read(*pool_ctx, obj, bl, len, off);
 }
 
-int Rados::trunc(rados_pool_t pool, const string& o, size_t size)
+int librados::PoolHandle::
+remove(const std::string& oid)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->trunc(*(RadosClient::PoolCtx *)pool, oid, size);
+  object_t obj(oid);
+  return pool_ctx->client->remove(*pool_ctx, obj);
 }
 
-int Rados::remove(rados_pool_t pool, const string& o)
+int librados::PoolHandle::
+trunc(const std::string& oid, size_t size)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->remove(*(RadosClient::PoolCtx *)pool, oid);
+  object_t obj(oid);
+  return pool_ctx->client->trunc(*pool_ctx, obj, size);
 }
 
-int Rados::read(rados_pool_t pool, const string& o, off_t off, bufferlist& bl, size_t len)
+int librados::PoolHandle::
+mapext(const std::string& oid, off_t off, size_t len, std::map<off_t, size_t>& m)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->read(*(RadosClient::PoolCtx *)pool, oid, off, bl, len);
+  object_t obj(oid);
+  return pool_ctx->client->mapext(*pool_ctx, oid, off, len, m);
 }
 
-int Rados::mapext(rados_pool_t pool, const string& o, off_t off, size_t len, std::map<off_t, size_t>& m)
+int librados::PoolHandle::
+sparse_read(const std::string& oid, std::map<off_t, size_t>& m,
+           bufferlist& bl, size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return ((RadosClient *)client)->mapext(*(RadosClient::PoolCtx *)pool, oid, off, len, m);
+  object_t obj(oid);
+  return pool_ctx->client->sparse_read(*pool_ctx, oid, m, bl, len, off);
 }
 
-int Rados::sparse_read(rados_pool_t pool, const string& o, off_t off, size_t len, std::map<off_t, size_t>& m, bufferlist& bl)
+int librados::PoolHandle::
+getxattr(const std::string& oid, const char *name, bufferlist& bl)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return ((RadosClient *)client)->sparse_read(*(RadosClient::PoolCtx *)pool, oid, off, len, m, bl);
+  object_t obj(oid);
+  return pool_ctx->client->getxattr(*pool_ctx, obj, name, bl);
 }
 
-int Rados::getxattr(rados_pool_t pool, const string& o, const char *name, bufferlist& bl)
+int librados::PoolHandle::
+getxattrs(const std::string& oid, map<std::string, bufferlist>& attrset)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->getxattr(*(RadosClient::PoolCtx *)pool, oid, name, bl);
+  object_t obj(oid);
+  return pool_ctx->client->getxattrs(*pool_ctx, obj, attrset);
 }
 
-int Rados::getxattrs(rados_pool_t pool, const string& o, map<std::string, bufferlist>& attrset)
+int librados::PoolHandle::
+setxattr(const std::string& oid, const char *name, bufferlist& bl)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->getxattrs(*(RadosClient::PoolCtx *)pool, oid, attrset);
+  object_t obj(oid);
+  return pool_ctx->client->setxattr(*pool_ctx, obj, name, bl);
 }
 
-int Rados::setxattr(rados_pool_t pool, const string& o, const char *name, bufferlist& bl)
+int librados::PoolHandle::
+rmxattr(const std::string& oid, const char *name)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->setxattr(*(RadosClient::PoolCtx *)pool, oid, name, bl);
+  object_t obj(oid);
+  return pool_ctx->client->rmxattr(*pool_ctx, obj, name);
 }
 
-int Rados::rmxattr(rados_pool_t pool, const string& o, const char *name)
+int librados::PoolHandle::
+stat(const std::string& oid, uint64_t *psize, time_t *pmtime)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->rmxattr(*(RadosClient::PoolCtx *)pool, oid, name);
+  object_t obj(oid);
+  return pool_ctx->client->stat(*pool_ctx, oid, psize, pmtime);
 }
 
-int Rados::stat(rados_pool_t pool, const string& o, uint64_t *psize, time_t *pmtime)
+int librados::PoolHandle::
+exec(const std::string& oid, const char *cls, const char *method,
+    bufferlist& inbl, bufferlist& outbl)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->stat(*(RadosClient::PoolCtx *)pool, oid, psize, pmtime);
+  object_t obj(oid);
+  return pool_ctx->client->exec(*pool_ctx, obj, cls, method, inbl, outbl);
 }
 
-int Rados::tmap_update(rados_pool_t pool, const string& o, bufferlist& cmdbl)
+int librados::PoolHandle::
+tmap_update(const std::string& oid, bufferlist& cmdbl)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->tmap_update(*(RadosClient::PoolCtx *)pool, oid, cmdbl);
+  object_t obj(oid);
+  return pool_ctx->client->tmap_update(*pool_ctx, obj, cmdbl);
 }
-int Rados::exec(rados_pool_t pool, const string& o, const char *cls, const char *method,
-               bufferlist& inbl, bufferlist& outbl)
+
+void librados::PoolHandle::
+snap_set_read(snap_t seq)
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->exec(*(RadosClient::PoolCtx *)pool, oid, cls, method, inbl, outbl);
+  pool_ctx->set_snap_read(seq);
 }
 
-int Rados::lookup_pool(const char *name)
+int librados::PoolHandle::
+selfmanaged_snap_set_write_ctx(snap_t seq, vector<snap_t>& snaps)
 {
-  return client->lookup_pool(name);
+  vector<snapid_t> snv;
+  snv.resize(snaps.size());
+  for (unsigned i=0; i<snaps.size(); i++)
+    snv[i] = snaps[i];
+  return pool_ctx->set_snap_write_context(seq, snv);
 }
 
-int Rados::open_pool(const char *name, rados_pool_t *pool)
+int librados::PoolHandle::
+snap_create(const char *snapname)
 {
-  if (!client)
-    return -EINVAL;
-  int poolid = client->lookup_pool(name);
-  if (poolid >= 0) {
-    RadosClient::PoolCtx *ctx = new RadosClient::PoolCtx(client, poolid, name, CEPH_NOSNAP);
-    if (!ctx)
-      return -ENOMEM;
+  return pool_ctx->client->snap_create(pool_ctx, snapname);
+}
 
-    *pool = (rados_pool_t)ctx;
-    return 0;
-  }
-  return poolid;
+int librados::PoolHandle::
+snap_lookup(const char *name, snap_t *snapid)
+{
+  return pool_ctx->client->snap_lookup(pool_ctx, name, snapid);
 }
 
-int Rados::close_pool(rados_pool_t pool)
+int librados::PoolHandle::
+snap_get_stamp(snap_t snapid, time_t *t)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  delete ctx;
-  return 0;
+  return pool_ctx->client->snap_get_stamp(pool_ctx, snapid, t);
 }
 
-// SNAPS
+int librados::PoolHandle::
+snap_get_name(snap_t snapid, std::string *s)
+{
+  return pool_ctx->client->snap_get_name(pool_ctx, snapid, s);
+}
 
-int Rados::snap_create(rados_pool_t pool, const char *snapname) {
-  if (!client) return -EINVAL;
-  return client->snap_create(pool, snapname);
+int librados::PoolHandle::
+snap_remove(const char *snapname)
+{
+  return pool_ctx->client->snap_remove(pool_ctx, snapname);
 }
 
-int Rados::snap_remove(rados_pool_t pool, const char *snapname) {
-  if (!client) return -EINVAL;
-  return client->snap_remove(pool, snapname);
+int librados::PoolHandle::
+snap_list(std::vector<snap_t> *snaps)
+{
+  return pool_ctx->client->snap_list(pool_ctx, snaps);
 }
 
-int Rados::snap_rollback_object(rados_pool_t pool, const std::string& oid,
-                               const char *snapname) {
-  if (!client) return -EINVAL;
-  return client->snap_rollback_object(pool, oid, snapname);
+int librados::PoolHandle::
+rollback(const std::string& oid, const char *snapname)
+{
+  return pool_ctx->client->rollback(pool_ctx, oid, snapname);
 }
 
-int Rados::selfmanaged_snap_create(rados_pool_t pool, uint64_t *snapid)
+int librados::PoolHandle::
+selfmanaged_snap_create(uint64_t *snapid)
 {
-  if (!client) return -EINVAL;
-  return client->selfmanaged_snap_create(pool, snapid);
+  return pool_ctx->client->selfmanaged_snap_create(pool_ctx, snapid);
 }
 
-int Rados::selfmanaged_snap_remove(rados_pool_t pool,
-                                  uint64_t snapid)
+int librados::PoolHandle::
+selfmanaged_snap_remove(uint64_t snapid)
 {
-  if (!client) return -EINVAL;
-  return client->selfmanaged_snap_remove(pool, snapid);
+  return pool_ctx->client->selfmanaged_snap_remove(pool_ctx, snapid);
 }
 
-int Rados::selfmanaged_snap_rollback_object(rados_pool_t pool,
-                                const std::string& oid,
-                                SnapContext& snapc, uint64_t snapid)
+int librados::PoolHandle::
+selfmanaged_snap_rollback(const std::string& oid, SnapContext& snapc,
+                          uint64_t snapid)
 {
   ::SnapContext sn;
-  if (!client) return -EINVAL;
   sn.seq = snapc.seq;
   sn.snaps.clear();
-  vector<snap_t>::iterator iter = snapc.snaps.begin();
+  std::vector<snap_t>::const_iterator iter = snapc.snaps.begin();
   for (; iter != snapc.snaps.end(); ++iter) {
     sn.snaps.push_back(*iter);
   }
-  return client->selfmanaged_snap_rollback_object(pool, oid, sn, snapid);
+  return pool_ctx->client->
+    selfmanaged_snap_rollback_object(pool_ctx, oid, sn, snapid);
 }
 
-void Rados::set_snap_read(rados_pool_t pool, snap_t seq)
+librados::ObjectIterator librados::PoolHandle::
+objects_begin()
 {
-  if (!client)
-    return;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  ctx->set_snap_read(seq);
+  rados_list_ctx_t listh;
+  rados_objects_list_open(pool_ctx, &listh);
+  return ObjectIterator(listh);
 }
 
-int Rados::set_snap_write_context(rados_pool_t pool, snap_t seq, vector<snap_t>& snaps)
+const librados::ObjectIterator& librados::PoolHandle::
+objects_end() const
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  vector<snapid_t> snv;
-  snv.resize(snaps.size());
-  for (unsigned i=0; i<snaps.size(); i++)
-    snv[i] = snaps[i];
-  return ctx->set_snap_write_context(seq, snv);
+  return ObjectIterator::__EndObjectIterator;
 }
 
-int Rados::snap_list(rados_pool_t pool, vector<snap_t> *snaps)
+uint64_t librados::PoolHandle::
+get_last_version()
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return client->snap_list(ctx, snaps);
+  eversion_t ver = pool_ctx->client->last_version(*pool_ctx);
+  return ver.version;
 }
 
-int Rados::snap_lookup(rados_pool_t pool, const char *name, snap_t *snapid)
+int librados::PoolHandle::
+aio_read(const std::string& oid, librados::AioCompletion *c,
+        bufferlist *pbl, size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return client->snap_lookup(ctx, name, snapid);
+  return pool_ctx->client->aio_read(*pool_ctx, oid, c->pc, pbl, len, off);
 }
 
-int Rados::snap_get_name(rados_pool_t pool, snap_t snapid, std::string *s)
+int librados::PoolHandle::
+aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
+               std::map<off_t,size_t> *m, bufferlist *data_bl,
+               size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return client->snap_get_name(ctx, snapid, s);
+  return pool_ctx->client->aio_sparse_read(*pool_ctx, oid, c->pc,
+                                          m, data_bl, len, off);
 }
-int Rados::snap_get_stamp(rados_pool_t pool, snap_t snapid, time_t *t)
+
+int librados::PoolHandle::
+aio_write(const std::string& oid, librados::AioCompletion *c, const bufferlist& bl,
+         size_t len, off_t off)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return client->snap_get_stamp(ctx, snapid, t);
+  return pool_ctx->client->aio_write(*pool_ctx, oid, c->pc, bl, len, off );
 }
 
-// AIO
-int Rados::aio_read(rados_pool_t pool, const string& oid, off_t off, bufferlist *pbl, size_t len,
-                   Rados::AioCompletion *c)
+int librados::PoolHandle::
+aio_write_full(const std::string& oid, librados::AioCompletion *c, const bufferlist& bl)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  RadosClient::AioCompletion *pc = (RadosClient::AioCompletion *)c->pc;
-  int r = client->aio_read(*ctx, oid, off, pbl, len, pc);
-  return r;
+  object_t obj(oid);
+  return pool_ctx->client->aio_write_full(*pool_ctx, obj, c->pc, bl);
 }
 
-int Rados::aio_sparse_read(pool_t pool, const std::string& oid, off_t off,
-                   std::map<off_t,size_t> *m, bufferlist *data_bl, size_t len,
-                   AioCompletion *c)
+int librados::PoolHandle::
+watch(const string& oid, uint64_t ver, uint64_t *cookie, librados::WatchCtx *ctx)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  RadosClient::AioCompletion *pc = (RadosClient::AioCompletion *)c->pc;
-  int r = client->aio_sparse_read(*ctx, oid, off, m, data_bl, len, pc);
-  return r;
+  object_t obj(oid);
+  return pool_ctx->client->watch(*pool_ctx, obj, ver, cookie, ctx);
 }
 
-int Rados::aio_write(rados_pool_t pool, const string& oid, off_t off, const bufferlist& bl, size_t len,
-                    AioCompletion *c)
+int librados::PoolHandle::
+unwatch(const string& oid, uint64_t handle)
 {
-  if (!client)
-    return -EINVAL;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  RadosClient::AioCompletion *pc = (RadosClient::AioCompletion *)c->pc;
-  int r = client->aio_write(*ctx, oid, off, bl, len, pc);
-  return r;
+  uint64_t cookie = handle;
+  object_t obj(oid);
+  return pool_ctx->client->unwatch(*pool_ctx, obj, cookie);
 }
 
-Rados::AioCompletion *Rados::aio_create_completion()
+int librados::PoolHandle::
+notify(const string& oid, uint64_t ver)
 {
-  if (!client)
-    return NULL;
-  RadosClient::AioCompletion *c = client->aio_create_completion();
-  return new AioCompletion(c);
+  object_t obj(oid);
+  return pool_ctx->client->notify(*pool_ctx, obj, ver);
 }
 
-Rados::AioCompletion *Rados::aio_create_completion(void *cb_arg, callback_t cb_complete, callback_t cb_safe)
+void librados::PoolHandle::
+set_notify_timeout(uint32_t timeout)
 {
-  if (!client)
-    return NULL;
-  RadosClient::AioCompletion *c = client->aio_create_completion(cb_arg, cb_complete, cb_safe);
-  return new AioCompletion(c);
+  pool_ctx->client->set_notify_timeout(*pool_ctx, timeout);
 }
 
-int Rados::AioCompletion::set_complete_callback(void *cb_arg, rados_callback_t cb)
+void librados::PoolHandle::
+set_assert_version(uint64_t ver)
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->set_complete_callback(cb_arg, cb);
+  pool_ctx->client->set_assert_version(*pool_ctx, ver);
 }
-int Rados::AioCompletion::set_safe_callback(void *cb_arg, rados_callback_t cb)
+
+const std::string& librados::PoolHandle::
+get_name() const
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->set_safe_callback(cb_arg, cb);
+  return name;
 }
-int Rados::AioCompletion::wait_for_complete()
+
+librados::PoolHandle::
+PoolHandle(PoolCtx *pool_ctx_)
+  : pool_ctx(pool_ctx_)
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->wait_for_complete();
 }
-int Rados::AioCompletion::wait_for_safe()
+
+///////////////////////////// Rados //////////////////////////////
+void librados::Rados::
+version(int *major, int *minor, int *extra)
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->wait_for_safe();
+  rados_version(major, minor, extra);
 }
-bool Rados::AioCompletion::is_complete()
+
+librados::Rados::
+Rados() : client(NULL)
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->is_complete();
 }
-bool Rados::AioCompletion::is_safe()
+
+librados::Rados::
+~Rados()
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->is_safe();
+  shutdown();
 }
-int Rados::AioCompletion::get_return_value()
+
+int librados::Rados::
+init(const char * const id)
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->get_return_value();
+  return rados_create((rados_t *)&client, id);
 }
-int Rados::AioCompletion::get_version()
+
+int librados::Rados::
+connect()
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  return c->get_version();
+  return client->connect();
 }
-void Rados::AioCompletion::release()
+
+void librados::Rados::
+shutdown()
 {
-  RadosClient::AioCompletion *c = (RadosClient::AioCompletion *)pc;
-  c->release();
+  if (!client)
+    return;
+  client->shutdown();
+  delete client;
+  client = NULL;
 }
 
-// watch/notify
-int Rados::watch(pool_t pool, const string& o,
-                 uint64_t ver, uint64_t *cookie, Rados::WatchCtx *ctx)
+int librados::Rados::
+conf_read_file(const char * const path) const
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->watch(*(RadosClient::PoolCtx *)pool, oid, ver, cookie, ctx);
+  return rados_conf_read_file((rados_t)client, path);
 }
 
-int Rados::unwatch(pool_t pool, const string& o, uint64_t handle)
+int librados::Rados::
+conf_set(const char *option, const char *value)
 {
-  uint64_t cookie = handle;
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->unwatch(*(RadosClient::PoolCtx *)pool, oid, cookie);
+  return rados_conf_set((rados_t)client, option, value);
 }
 
-int Rados::notify(pool_t pool, const string& o, uint64_t ver)
+void librados::Rados::
+reopen_log()
 {
-  if (!client)
-    return -EINVAL;
-  object_t oid(o);
-  return client->notify(*(RadosClient::PoolCtx *)pool, oid, ver);
+  rados_reopen_log((rados_t)client);
 }
 
-void Rados::set_assert_version(pool_t pool, uint64_t ver)
+int librados::Rados::
+conf_get(const char *option, std::string &val)
 {
-  if (!client)
-    return;
-  client->set_assert_version(*(RadosClient::PoolCtx *)pool, ver);
+  char *str;
+  int ret = g_conf.get_val(option, &str, -1);
+  if (ret)
+    return ret;
+  val = str;
+  free(str);
+  return 0;
 }
 
-void Rados::set_notify_timeout(pool_t pool, uint32_t timeout)
+int librados::Rados::
+pool_create(const char *name)
 {
-  if (!client)
-    return;
-  client->set_notify_timeout(*(RadosClient::PoolCtx *)pool, timeout);
+  string str(name);
+  return client->pool_create(str);
 }
+
+int librados::Rados::
+pool_create(const char *name, uint64_t auid)
+{
+  string str(name);
+  return client->pool_create(str, auid);
+}
+
+int librados::Rados::
+pool_create(const char *name, uint64_t auid, __u8 crush_rule)
+{
+  string str(name);
+  return client->pool_create(str, auid, crush_rule);
 }
 
-// ---------------------------------------------
+int librados::Rados::
+pool_list(std::list<std::string>& v)
+{
+  return client->pool_list(v);
+}
 
+int librados::Rados::
+pool_open(const char *name, PoolHandle &pool)
+{
+  rados_pool_t p;
+  int ret = rados_pool_open((rados_t)client, name, &p);
+  if (ret)
+    return ret;
+  pool.pool_ctx = (PoolCtx*)p;
+  pool.name = name;
+  return 0;
+}
+
+int librados::Rados::
+pool_lookup(const char *name)
+{
+  return client->lookup_pool(name);
+}
+
+int librados::Rados::
+get_pool_stats(std::list<string>& v, std::map<string,pool_stat_t>& result)
+{
+  map<string,::pool_stat_t> rawresult;
+  int r = client->get_pool_stats(v, rawresult);
+  for (map<string,::pool_stat_t>::iterator p = rawresult.begin();
+       p != rawresult.end();
+       p++) {
+    pool_stat_t& v = result[p->first];
+    v.num_kb = p->second.num_kb;
+    v.num_bytes = p->second.num_bytes;
+    v.num_objects = p->second.num_objects;
+    v.num_object_clones = p->second.num_object_clones;
+    v.num_object_copies = p->second.num_object_copies;
+    v.num_objects_missing_on_primary = p->second.num_objects_missing_on_primary;
+    v.num_objects_unfound = p->second.num_objects_unfound;
+    v.num_objects_degraded = p->second.num_objects_degraded;
+    v.num_rd = p->second.num_rd;
+    v.num_rd_kb = p->second.num_rd_kb;
+    v.num_wr = p->second.num_wr;
+    v.num_wr_kb = p->second.num_wr_kb;
+  }
+  return r;
+}
+
+int librados::Rados::
+get_fs_stats(statfs_t& result)
+{
+  ceph_statfs stats;
+  int r = client->get_fs_stats(stats);
+  result.kb = stats.kb;
+  result.kb_used = stats.kb_used;
+  result.kb_avail = stats.kb_avail;
+  result.num_objects = stats.num_objects;
+  return r;
+}
+
+librados::AioCompletion *librados::Rados::
+aio_create_completion()
+{
+  AioCompletionImpl *c = RadosClient::aio_create_completion();
+  return new AioCompletion(c);
+}
+
+librados::AioCompletion *librados::Rados::
+aio_create_completion(void *cb_arg, callback_t cb_complete, callback_t cb_safe)
+{
+  AioCompletionImpl *c = RadosClient::aio_create_completion(cb_arg, cb_complete, cb_safe);
+  return new AioCompletion(c);
+}
+
+///////////////////////////// C API //////////////////////////////
 static Mutex rados_init_mutex("rados_init");
 static int rados_initialized = 0;
 
@@ -2405,7 +2512,7 @@ extern "C" int rados_connect(rados_t cluster)
   return radosp->connect();
 }
 
-extern "C" void rados_destroy(rados_t cluster)
+extern "C" void rados_shutdown(rados_t cluster)
 {
   RadosClient *radosp = (RadosClient *)cluster;
   radosp->shutdown();
@@ -2466,7 +2573,7 @@ extern "C" int rados_pool_list(rados_t cluster, char *buf, int len)
 {
   RadosClient *client = (RadosClient *)cluster;
   std::list<std::string> pools;
-  client->list_pools(pools);
+  client->pool_list(pools);
 
   char *b = buf;
   if (b)
@@ -2495,7 +2602,7 @@ extern "C" int rados_pool_open(rados_t cluster, const char *name, rados_pool_t *
   RadosClient *radosp = (RadosClient *)cluster;
   int poolid = radosp->lookup_pool(name);
   if (poolid >= 0) {
-    RadosClient::PoolCtx *ctx = new RadosClient::PoolCtx(radosp, poolid, name, CEPH_NOSNAP);
+    PoolCtx *ctx = new PoolCtx(radosp, poolid, name, CEPH_NOSNAP);
     if (!ctx)
       return -ENOMEM;
     *pool = ctx;
@@ -2506,14 +2613,14 @@ extern "C" int rados_pool_open(rados_t cluster, const char *name, rados_pool_t *
 
 extern "C" int rados_pool_close(rados_pool_t pool)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   delete ctx;
   return 0;
 }
 
 extern "C" int rados_pool_stat(rados_pool_t pool, struct rados_pool_stat_t *stats)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   list<string> ls;
   ls.push_back(ctx->name);
   map<string, ::pool_stat_t> rawresult;
@@ -2541,14 +2648,14 @@ extern "C" int rados_pool_stat(rados_pool_t pool, struct rados_pool_stat_t *stat
 
 extern "C" void rados_snap_set_read(rados_pool_t pool, rados_snap_t seq)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   ctx->set_snap_read((snapid_t)seq);
 }
 
 extern "C" int rados_snap_set_write_context(rados_pool_t pool, rados_snap_t seq,
                                       rados_snap_t *snaps, int num_snaps)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   vector<snapid_t> snv;
   snv.resize(num_snaps);
   for (int i=0; i<num_snaps; i++)
@@ -2558,16 +2665,16 @@ extern "C" int rados_snap_set_write_context(rados_pool_t pool, rados_snap_t seq,
 
 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;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist bl;
   bl.append(buf, len);
-  return ctx->client->write(*ctx, oid, off, bl, len);
+  return ctx->client->write(*ctx, oid, bl, len, off);
 }
 
 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;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist bl;
   bl.append(buf, len);
@@ -2576,29 +2683,29 @@ extern "C" int rados_write_full(rados_pool_t pool, const char *o, const char *bu
 
 extern "C" int rados_trunc(rados_pool_t pool, const char *o, size_t size)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->trunc(*ctx, oid, size);
 }
 
 extern "C" int rados_remove(rados_pool_t pool, const char *o)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->remove(*ctx, oid);
 }
 
 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;
+  PoolCtx *ctx = (PoolCtx *)pool;
   int ret;
   object_t oid(o);
 
   bufferlist bl;
   bufferptr bp = buffer::create_static(len, buf);
   bl.push_back(bp);
-  
-  ret = ctx->client->read(*ctx, oid, off, bl, len);
+
+  ret = ctx->client->read(*ctx, oid, bl, len, off);
   if (ret >= 0) {
     if (bl.length() > len)
       return -ERANGE;
@@ -2612,7 +2719,7 @@ extern "C" int rados_read(rados_pool_t pool, const char *o, char *buf, size_t le
 
 extern "C" uint64_t rados_get_last_version(rados_pool_t pool)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   eversion_t ver = ctx->client->last_version(*ctx);
   return ver.version;
 }
@@ -2621,7 +2728,7 @@ extern "C" int rados_pool_create(rados_t cluster, const char *name)
 {
   RadosClient *radosp = (RadosClient *)cluster;
   string sname(name);
-  return radosp->create_pool(sname);
+  return radosp->pool_create(sname);
 }
 
 extern "C" int rados_pool_create_with_auid(rados_t cluster, const char *name,
@@ -2629,7 +2736,7 @@ extern "C" int rados_pool_create_with_auid(rados_t cluster, const char *name,
 {
   RadosClient *radosp = (RadosClient *)cluster;
   string sname(name);
-  return radosp->create_pool(sname, auid);
+  return radosp->pool_create(sname, auid);
 }
 
 extern "C" int rados_pool_create_with_crush_rule(rados_t cluster, const char *name,
@@ -2637,7 +2744,7 @@ extern "C" int rados_pool_create_with_crush_rule(rados_t cluster, const char *na
 {
   RadosClient *radosp = (RadosClient *)cluster;
   string sname(name);
-  return radosp->create_pool(sname, 0, crush_rule);
+  return radosp->pool_create(sname, 0, crush_rule);
 }
 
 extern "C" int rados_pool_create_with_all(rados_t cluster, const char *name,
@@ -2645,32 +2752,32 @@ extern "C" int rados_pool_create_with_all(rados_t cluster, const char *name,
 {
   RadosClient *radosp = (RadosClient *)cluster;
   string sname(name);
-  return radosp->create_pool(sname, auid, crush_rule);
+  return radosp->pool_create(sname, auid, crush_rule);
 }
 
 extern "C" int rados_pool_delete(rados_pool_t pool)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return ctx->client->delete_pool(ctx);
+  PoolCtx *ctx = (PoolCtx *)pool;
+  return ctx->client->pool_delete(ctx);
 }
 
 extern "C" int rados_pool_change_auid(rados_pool_t pool, uint64_t auid)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return ctx->client->change_pool_auid(ctx, auid);
+  PoolCtx *ctx = (PoolCtx *)pool;
+  return ctx->client->pool_change_auid(ctx, auid);
 }
 
 // snaps
 
 extern "C" int rados_pool_snap_create(rados_pool_t pool, const char *snapname)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   return ctx->client->snap_create(ctx, snapname);
 }
 
 extern "C" int rados_pool_snap_remove(rados_pool_t pool, const char *snapname)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   return ctx->client->snap_remove(ctx, snapname);
 }
 
@@ -2678,28 +2785,28 @@ extern "C" int rados_pool_snap_rollback_object(rados_pool_t pool,
                                          const char *oid,
                                          const char *snapname)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-  return ctx->client->snap_rollback_object(ctx, oid, snapname);
+  PoolCtx *ctx = (PoolCtx *)pool;
+  return ctx->client->rollback(ctx, oid, snapname);
 }
 
 extern "C" int rados_pool_selfmanaged_snap_create(rados_pool_t pool,
                                             uint64_t *snapid)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   return ctx->client->selfmanaged_snap_create(ctx, snapid);
 }
 
 extern "C" int rados_pool_selfmanaged_snap_remove(rados_pool_t pool,
                                             uint64_t snapid)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   return ctx->client->selfmanaged_snap_remove(ctx, snapid);
 }
 
 extern "C" int rados_pool_snap_list(rados_pool_t pool, rados_snap_t *snaps,
                                    int maxlen)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   vector<uint64_t> snapvec;
   int r = ctx->client->snap_list(ctx, &snapvec);
   if (r < 0)
@@ -2715,14 +2822,14 @@ extern "C" int rados_pool_snap_list(rados_pool_t pool, rados_snap_t *snaps,
 extern "C" int rados_pool_snap_lookup(rados_pool_t pool, const char *name,
                                      rados_snap_t *id)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   return ctx->client->snap_lookup(ctx, name, (uint64_t *)id);
 }
 
 extern "C" int rados_pool_snap_get_name(rados_pool_t pool, rados_snap_t id,
                                        char *name, int maxlen)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   std::string sname;
   int r = ctx->client->snap_get_name(ctx, id, &sname);
   if (r < 0)
@@ -2737,7 +2844,7 @@ extern "C" int rados_pool_snap_get_name(rados_pool_t pool, rados_snap_t id,
 extern "C" int rados_getxattr(rados_pool_t pool, const char *o, const char *name,
                              char *buf, size_t len)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   int ret;
   object_t oid(o);
   bufferlist bl;
@@ -2754,7 +2861,7 @@ extern "C" int rados_getxattr(rados_pool_t pool, const char *o, const char *name
 
 extern "C" int rados_setxattr(rados_pool_t pool, const char *o, const char *name, const char *buf, size_t len)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist bl;
   bl.append(buf, len);
@@ -2763,21 +2870,21 @@ extern "C" int rados_setxattr(rados_pool_t pool, const char *o, const char *name
 
 extern "C" int rados_rmxattr(rados_pool_t pool, const char *o, const char *name)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->rmxattr(*ctx, oid, name);
 }
 
 extern "C" int rados_stat(rados_pool_t pool, const char *o, uint64_t *psize, time_t *pmtime)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->stat(*ctx, oid, psize, pmtime);
 }
 
 extern "C" int rados_tmap_update(rados_pool_t pool, const char *o, const char *cmdbuf, size_t cmdbuflen)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist cmdbl;
   cmdbl.append(cmdbuf, cmdbuflen);
@@ -2787,7 +2894,7 @@ extern "C" int rados_tmap_update(rados_pool_t pool, const char *o, const char *c
 extern "C" int rados_exec(rados_pool_t pool, const char *o, const char *cls, const char *method,
                          const char *inbuf, size_t in_len, char *buf, size_t out_len)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist inbl, outbl;
   int ret;
@@ -2808,7 +2915,7 @@ extern "C" int rados_exec(rados_pool_t pool, const char *o, const char *cls, con
 
 extern "C" int rados_objects_list_open(rados_pool_t pool, rados_list_ctx_t *listh)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   Objecter::ListContext *h = new Objecter::ListContext;
   h->pool_id = ctx->poolid;
   h->pool_snap_seq = ctx->snap_seq;
@@ -2832,7 +2939,7 @@ extern "C" int rados_objects_list_next(rados_list_ctx_t listctx, const char **en
   if (!h->list.empty())
     // so let's kill the previously-returned object
     h->list.pop_front();
-  
+
   if (h->list.empty()) {
     ret = lh->ctx->client->list(lh->lc, RADOS_LIST_MAX_ENTRIES);
     if (!h->list.size())
@@ -2857,71 +2964,74 @@ extern "C" int rados_aio_create_completion(void *cb_arg, rados_callback_t cb_com
 
 extern "C" int rados_aio_wait_for_complete(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->wait_for_complete();
+  return ((AioCompletionImpl*)c)->wait_for_complete();
 }
 
 extern "C" int rados_aio_wait_for_safe(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->wait_for_safe();
+  return ((AioCompletionImpl*)c)->wait_for_safe();
 }
 
 extern "C" int rados_aio_is_complete(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->is_complete();
+  return ((AioCompletionImpl*)c)->is_complete();
 }
 
 extern "C" int rados_aio_is_safe(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->is_safe();
+  return ((AioCompletionImpl*)c)->is_safe();
 }
 
 extern "C" int rados_aio_get_return_value(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->get_return_value();
+  return ((AioCompletionImpl*)c)->get_return_value();
 }
 
 extern "C" uint64_t rados_aio_get_version(rados_completion_t c)
 {
-  return ((RadosClient::AioCompletion *)c)->get_version();
+  return ((AioCompletionImpl*)c)->get_version();
 }
 
 extern "C" void rados_aio_release(rados_completion_t c)
 {
-  ((RadosClient::AioCompletion *)c)->put();
+  ((AioCompletionImpl*)c)->put();
 }
 
 extern "C" int rados_aio_read(rados_pool_t pool, const char *o,
                               rados_completion_t completion,
                               char *buf, size_t len, off_t off)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
-  return ctx->client->aio_read(*ctx, oid, off, buf, len, (RadosClient::AioCompletion*)completion);
+  return ctx->client->aio_read(*ctx, oid,
+            (AioCompletionImpl*)completion, buf, len, off);
 }
 
 extern "C" int rados_aio_write(rados_pool_t pool, const char *o,
                                rados_completion_t completion,
                                const char *buf, size_t len, off_t off)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist bl;
   bl.append(buf, len);
-  return ctx->client->aio_write(*ctx, oid, off, bl, len, (RadosClient::AioCompletion*)completion);
+  return ctx->client->aio_write(*ctx, oid,
+             (AioCompletionImpl*)completion, bl, len, off);
 }
 
 extern "C" int rados_aio_write_full(rados_pool_t pool, const char *o,
                         rados_completion_t completion,
-                        const char *buf, size_t len, off_t off)
+                        const char *buf, size_t len)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   bufferlist bl;
   bl.append(buf, len);
-  return ctx->client->aio_write_full(*ctx, oid, bl, (RadosClient::AioCompletion*)completion);
+  return ctx->client->aio_write_full(*ctx, oid,
+             (AioCompletionImpl*)completion, bl);
 }
 
-struct C_WatchCB : public librados::Rados::WatchCtx {
+struct C_WatchCB : public librados::WatchCtx {
   rados_watchcb_t wcb;
   void *arg;
   C_WatchCB(rados_watchcb_t _wcb, void *_arg) : wcb(_wcb), arg(_arg) {}
@@ -2934,7 +3044,7 @@ int rados_watch(rados_pool_t pool, const char *o, uint64_t ver, uint64_t *handle
                 rados_watchcb_t watchcb, void *arg)
 {
   uint64_t *cookie = handle;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   C_WatchCB *wc = new C_WatchCB(watchcb, arg);
   return ctx->client->watch(*ctx, oid, ver, cookie, wc);
@@ -2943,14 +3053,14 @@ int rados_watch(rados_pool_t pool, const char *o, uint64_t ver, uint64_t *handle
 int rados_unwatch(rados_pool_t pool, const char *o, uint64_t handle)
 {
   uint64_t cookie = handle;
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->unwatch(*ctx, oid, cookie);
 }
 
 int rados_notify(rados_pool_t pool, const char *o, uint64_t ver)
 {
-  RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+  PoolCtx *ctx = (PoolCtx *)pool;
   object_t oid(o);
   return ctx->client->notify(*ctx, oid, ver);
 }
index cf90ad54cb8b2e4cdff32eb490935791a6594b4e..c2e88243b2fd4e3cfbba40bb4602f8ea4293f554 100644 (file)
@@ -46,7 +46,7 @@ namespace librbd {
 
   using ceph::bufferlist;
   using librados::snap_t;
-  using librados::pool_t;
+  using librados::PoolHandle;
   using librados::Rados;
 
   class WatchCtx;
@@ -64,12 +64,12 @@ namespace librbd {
     std::map<std::string, struct SnapInfo> snaps_by_name;
     uint64_t snapid;
     std::string name;
-    pool_t pool;
+    PoolHandle &pool;
     WatchCtx *wctx;
     bool needs_refresh;
     Mutex lock;
 
-    ImageCtx(std::string imgname, pool_t p) : snapid(0),
+    ImageCtx(std::string imgname, PoolHandle& p) : snapid(0),
                                                 name(imgname),
                                                 pool(p),
                                                 needs_refresh(true),
@@ -94,7 +94,7 @@ namespace librbd {
     }
   };
 
-  class WatchCtx : public librados::Rados::WatchCtx {
+  class WatchCtx : public librados::WatchCtx {
     ImageCtx *ictx;
     bool valid;
     Mutex lock;
@@ -201,36 +201,36 @@ namespace librbd {
   void rados_aio_sparse_read_cb(rados_completion_t cb, void *arg);
 
   int snap_set(ImageCtx *ictx, const char *snap_name);
-  int list(pool_t pool, std::vector<string>& names);
-  int create(pool_t pool, string& md_oid, const char *imgname, uint64_t size, int *order);
-  int rename(pool_t pool, const char *srcname, const char *dstname);
+  int list(PoolHandle& pool, std::vector<string>& names);
+  int create(PoolHandle& pool, string& md_oid, const char *imgname, uint64_t size, int *order);
+  int rename(PoolHandle& pool, const char *srcname, const char *dstname);
   int info(ImageCtx *ictx, image_info_t& info, size_t image_size);
-  int remove(pool_t pool, const char *imgname);
+  int remove(PoolHandle& pool, const char *imgname);
   int resize(ImageCtx *ictx, uint64_t size);
   int snap_create(ImageCtx *ictx, const char *snap_name);
   int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps);
   int snap_rollback(ImageCtx *ictx, const char *snap_name);
   int snap_remove(ImageCtx *ictx, const char *snap_name);
   int add_snap(ImageCtx *ictx, const char *snap_name);
-  int rm_snap(pool_t pool, string& md_oid, const char *snap_name);
+  int rm_snap(PoolHandle& pool, string& md_oid, const char *snap_name);
   int ictx_check(ImageCtx *ictx);
   int ictx_refresh(ImageCtx *ictx, const char *snap_name);
-  int copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *destname);
+  int copy(PoolHandle& src_pool, const char *srcname, PoolHandle& dest_pool, const char *destname);
 
-  int open_image(pool_t pool, ImageCtx *ictx, const char *name, const char *snap_name);
+  int open_image(PoolHandle& pool, ImageCtx *ictx, const char *name, const char *snap_name);
   void close_image(ImageCtx *ictx);
 
-  void trim_image(pool_t pool, rbd_obj_header_ondisk *header, uint64_t newsize);
-  int read_rbd_info(pool_t pool, string& info_oid, struct rbd_info *info);
-
-  int touch_rbd_info(pool_t pool, string& info_oid);
-  int rbd_assign_bid(pool_t pool, string& info_oid, uint64_t *id);
-  int read_header_bl(pool_t pool, string& md_oid, bufferlist& header, uint64_t *ver);
-  int notify_change(pool_t pool, string& oid, uint64_t *pver, ImageCtx *ictx);
-  int read_header(pool_t pool, string& md_oid, struct rbd_obj_header_ondisk *header, uint64_t *ver);
-  int write_header(pool_t pool, string& md_oid, bufferlist& header);
-  int tmap_set(pool_t pool, string& imgname);
-  int tmap_rm(pool_t pool, string& imgname);
+  void trim_image(PoolHandle& pool, rbd_obj_header_ondisk *header, uint64_t newsize);
+  int read_rbd_info(PoolHandle& pool, string& info_oid, struct rbd_info *info);
+
+  int touch_rbd_info(PoolHandle& pool, string& info_oid);
+  int rbd_assign_bid(PoolHandle& pool, string& info_oid, uint64_t *id);
+  int read_header_bl(PoolHandle& pool, string& md_oid, bufferlist& header, uint64_t *ver);
+  int notify_change(PoolHandle& pool, string& oid, uint64_t *pver, ImageCtx *ictx);
+  int read_header(PoolHandle& pool, string& md_oid, struct rbd_obj_header_ondisk *header, uint64_t *ver);
+  int write_header(PoolHandle& pool, string& md_oid, bufferlist& header);
+  int tmap_set(PoolHandle& pool, string& imgname);
+  int tmap_rm(PoolHandle& pool, string& imgname);
   int rollback_image(ImageCtx *ictx, uint64_t snapid);
   void image_info(rbd_obj_header_ondisk& header, image_info_t& info, size_t info_size);
   string get_block_oid(rbd_obj_header_ondisk *header, uint64_t num);
@@ -360,27 +360,25 @@ int init_rbd_info(struct rbd_info *info)
   return 0;
 }
 
-void trim_image(pool_t pool, rbd_obj_header_ondisk *header, uint64_t newsize)
+void trim_image(PoolHandle& pool, rbd_obj_header_ondisk *header, uint64_t newsize)
 {
   uint64_t numseg = get_max_block(header);
   uint64_t start = get_block_num(header, newsize);
-  Rados rados(pool);
   dout(2) << "trimming image data from " << numseg << " to " << start << " objects..." << dendl;
   for (uint64_t i=start; i<numseg; i++) {
     string oid = get_block_oid(header, i);
-    rados.remove(pool, oid);
+    pool.remove(oid);
     if ((i & 127) == 0) {
       dout(2) << "\r\t" << i << "/" << numseg << dendl;
     }
   }
 }
 
-int read_rbd_info(pool_t pool, string& info_oid, struct rbd_info *info)
+int read_rbd_info(PoolHandle& pool, string& info_oid, struct rbd_info *info)
 {
   int r;
   bufferlist bl;
-  Rados rados(pool);
-  r = rados.read(pool, info_oid, 0, bl, sizeof(*info));
+  r = pool.read(info_oid, bl, sizeof(*info), 0);
   if (r < 0)
     return r;
   if (r == 0) {
@@ -394,27 +392,25 @@ int read_rbd_info(pool_t pool, string& info_oid, struct rbd_info *info)
   return 0;
 }
 
-int touch_rbd_info(pool_t pool, string& info_oid)
+int touch_rbd_info(PoolHandle& pool, string& info_oid)
 {
   bufferlist bl;
-  Rados rados(pool);
-  int r = rados.write(pool, info_oid, 0, bl, 0);
+  int r = pool.write(info_oid, bl, 0, 0);
   if (r < 0)
     return r;
   return 0;
 }
 
-int rbd_assign_bid(pool_t pool, string& info_oid, uint64_t *id)
+int rbd_assign_bid(PoolHandle& pool, string& info_oid, uint64_t *id)
 {
   bufferlist bl, out;
-  Rados rados(pool);
   *id = 0;
 
   int r = touch_rbd_info(pool, info_oid);
   if (r < 0)
     return r;
 
-  r = rados.exec(pool, info_oid, "rbd", "assign_bid", bl, out);
+  r = pool.exec(info_oid, "rbd", "assign_bid", bl, out);
   if (r < 0)
     return r;
 
@@ -425,29 +421,27 @@ int rbd_assign_bid(pool_t pool, string& info_oid, uint64_t *id)
 }
 
 
-int read_header_bl(pool_t pool, string& md_oid, bufferlist& header, uint64_t *ver)
+int read_header_bl(PoolHandle& pool, string& md_oid, bufferlist& header, uint64_t *ver)
 {
   int r;
-  Rados rados(pool);
 #define READ_SIZE 4096
   do {
     bufferlist bl;
-    r = rados.read(pool, md_oid, 0, bl, READ_SIZE);
+    r = pool.read(md_oid, bl, READ_SIZE, 0);
     if (r < 0)
       return r;
     header.claim_append(bl);
    } while (r == READ_SIZE);
 
   if (ver)
-    *ver = rados.get_last_version(pool);
+    *ver = pool.get_last_version();
 
   return 0;
 }
 
-int notify_change(pool_t pool, string& oid, uint64_t *pver, ImageCtx *ictx)
+int notify_change(PoolHandle& pool, string& oid, uint64_t *pver, ImageCtx *ictx)
 {
   uint64_t ver;
-  Rados rados(pool);
 
   if (ictx) {
     ictx->lock.Lock();
@@ -458,15 +452,14 @@ int notify_change(pool_t pool, string& oid, uint64_t *pver, ImageCtx *ictx)
   if (pver)
     ver = *pver;
   else
-    ver = rados.get_last_version(pool);
-  rados.notify(pool, oid, ver);
+    ver = pool.get_last_version();
+  pool.notify(oid, ver);
   return 0;
 }
 
-int read_header(pool_t pool, string& md_oid, struct rbd_obj_header_ondisk *header, uint64_t *ver)
+int read_header(PoolHandle& pool, string& md_oid, struct rbd_obj_header_ondisk *header, uint64_t *ver)
 {
   bufferlist header_bl;
-  Rados rados(pool);
   int r = read_header_bl(pool, md_oid, header_bl, ver);
   if (r < 0)
     return r;
@@ -477,42 +470,38 @@ int read_header(pool_t pool, string& md_oid, struct rbd_obj_header_ondisk *heade
   return 0;
 }
 
-int write_header(pool_t pool, string& md_oid, bufferlist& header)
+int write_header(PoolHandle& pool, string& md_oid, bufferlist& header)
 {
   bufferlist bl;
-  Rados rados(pool);
-  int r = rados.write(pool, md_oid, 0, header, header.length());
+  int r = pool.write(md_oid, header, header.length(), 0);
 
   notify_change(pool, md_oid, NULL, NULL);
 
   return r;
 }
 
-int tmap_set(pool_t pool, string& imgname)
+int tmap_set(PoolHandle& pool, string& imgname)
 {
   bufferlist cmdbl, emptybl;
-  Rados rados(pool);
   __u8 c = CEPH_OSD_TMAP_SET;
   ::encode(c, cmdbl);
   ::encode(imgname, cmdbl);
   ::encode(emptybl, cmdbl);
-  return rados.tmap_update(pool, RBD_DIRECTORY, cmdbl);
+  return pool.tmap_update(RBD_DIRECTORY, cmdbl);
 }
 
-int tmap_rm(pool_t pool, string& imgname)
+int tmap_rm(PoolHandle& pool, string& imgname)
 {
   bufferlist cmdbl;
-  Rados rados(pool);
   __u8 c = CEPH_OSD_TMAP_RM;
   ::encode(c, cmdbl);
   ::encode(imgname, cmdbl);
-  return rados.tmap_update(pool, RBD_DIRECTORY, cmdbl);
+  return pool.tmap_update(RBD_DIRECTORY, cmdbl);
 }
 
 int rollback_image(ImageCtx *ictx, uint64_t snapid)
 {
   uint64_t numseg = get_max_block(&(ictx->header));
-  Rados rados(ictx->pool);
 
   for (uint64_t i = 0; i < numseg; i++) {
     int r;
@@ -524,18 +513,17 @@ int rollback_image(ImageCtx *ictx, uint64_t snapid)
     for (; iter != ictx->snapc.snaps.end(); ++iter) {
       sn.snaps.push_back(*iter);
     }
-    r = rados.selfmanaged_snap_rollback_object(ictx->pool, oid, sn, snapid);
+    r = ictx->pool.selfmanaged_snap_rollback(oid, sn, snapid);
     if (r < 0 && r != -ENOENT)
       return r;
   }
   return 0;
 }
 
-int list(pool_t pool, std::vector<std::string>& names)
+int list(PoolHandle& pool, std::vector<std::string>& names)
 {
   bufferlist bl;
-  Rados rados(pool);
-  int r = rados.read(pool, RBD_DIRECTORY, 0, bl, 0);
+  int r = pool.read(RBD_DIRECTORY, bl, 0, 0);
   if (r < 0)
     return r;
 
@@ -555,16 +543,15 @@ int snap_create(ImageCtx *ictx, const char *snap_name)
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
-
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
-  r = rados.set_snap_write_context(ictx->pool, ictx->snapc.seq, ictx->snaps);
+  r = ictx->pool.selfmanaged_snap_set_write_ctx(ictx->snapc.seq, ictx->snaps);
   if (r < 0)
     return r;
 
-  rados.set_snap_read(ictx->pool, 0);
+  // probably a bug: what's so special about snap 0? (as opposed to CEPH_NOSNAP, etc?)
+  ictx->pool.snap_set_read(0);
   r = add_snap(ictx, snap_name);
   notify_change(ictx->pool, md_oid, NULL, ictx);
   return r;
@@ -576,8 +563,6 @@ int snap_remove(ImageCtx *ictx, const char *snap_name)
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
-
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
@@ -585,26 +570,24 @@ int snap_remove(ImageCtx *ictx, const char *snap_name)
   if (r < 0)
     return r;
 
-  r = rados.set_snap_write_context(ictx->pool, ictx->snapc.seq, ictx->snaps);
+  r = ictx->pool.selfmanaged_snap_set_write_ctx(ictx->snapc.seq, ictx->snaps);
   if (r < 0)
     return r;
 
-  rados.set_snap_read(ictx->pool, ictx->snapid);
+  ictx->pool.snap_set_read(ictx->snapid);
 
   r = rm_snap(ictx->pool, md_oid, snap_name);
-  r = rados.selfmanaged_snap_remove(ictx->pool, ictx->snapid);
+  r = ictx->pool.selfmanaged_snap_remove(ictx->snapid);
   notify_change(ictx->pool, md_oid, NULL, ictx);
 
   return r;
 }
 
-int create(pool_t pool, string& md_oid, const char *imgname,
+int create(PoolHandle& pool, string& md_oid, const char *imgname,
                              uint64_t size, int *order)
 {
-  Rados rados(pool);
-
   // make sure it doesn't already exist
-  int r = rados.stat(pool, md_oid, NULL, NULL);
+  int r = pool.stat(md_oid, NULL, NULL);
   if (r == 0) {
     derr << "rbd image header " << md_oid << " already exists" << dendl;
     return -EEXIST;
@@ -630,14 +613,14 @@ int create(pool_t pool, string& md_oid, const char *imgname,
   ::encode(c, cmdbl);
   ::encode(imgname, cmdbl);
   ::encode(emptybl, cmdbl);
-  r = rados.tmap_update(pool, RBD_DIRECTORY, cmdbl);
+  r = pool.tmap_update(RBD_DIRECTORY, cmdbl);
   if (r < 0) {
     derr << "error adding img to directory: " << strerror(-r)<< dendl;
     return r;
   }
 
   dout(2) << "creating rbd image..." << dendl;
-  r = rados.write(pool, md_oid, 0, bl, bl.length());
+  r = pool.write(md_oid, bl, bl.length(), 0);
   if (r < 0) {
     derr << "error writing header: " << strerror(-r) << dendl;
     return r;
@@ -647,9 +630,8 @@ int create(pool_t pool, string& md_oid, const char *imgname,
   return 0;
 }
 
-int rename(pool_t pool, const char *srcname, const char *dstname)
+int rename(PoolHandle& pool, const char *srcname, const char *dstname)
 {
-  Rados rados(pool);
   string md_oid = srcname;
   md_oid += RBD_SUFFIX;
   string dst_md_oid = dstname;
@@ -663,7 +645,7 @@ int rename(pool_t pool, const char *srcname, const char *dstname)
     derr << "error reading header: " << md_oid << ": " << strerror(-r) << dendl;
     return r;
   }
-  r = rados.stat(pool, dst_md_oid, NULL, NULL);
+  r = pool.stat(dst_md_oid, NULL, NULL);
   if (r == 0) {
     derr << "rbd image header " << dst_md_oid << " already exists" << dendl;
     return -EEXIST;
@@ -675,7 +657,7 @@ int rename(pool_t pool, const char *srcname, const char *dstname)
   }
   r = tmap_set(pool, dstname_str);
   if (r < 0) {
-    rados.remove(pool, dst_md_oid);
+    pool.remove(dst_md_oid);
     derr << "can't add " << dst_md_oid << " to directory" << dendl;
     return r;
   }
@@ -683,7 +665,7 @@ int rename(pool_t pool, const char *srcname, const char *dstname)
   if (r < 0)
     derr << "warning: couldn't remove old entry from directory (" << imgname_str << ")" << dendl;
 
-  r = rados.remove(pool, md_oid);
+  r = pool.remove(md_oid);
   if (r < 0)
     derr << "warning: couldn't remove old metadata" << dendl;
   notify_change(pool, md_oid, NULL, NULL);
@@ -701,9 +683,8 @@ int info(ImageCtx *ictx, image_info_t& info, size_t infosize)
   return 0;
 }
 
-int remove(pool_t pool, const char *imgname)
+int remove(PoolHandle& pool, const char *imgname)
 {
-  Rados rados(pool);
   string md_oid = imgname;
   md_oid += RBD_SUFFIX;
 
@@ -712,7 +693,7 @@ int remove(pool_t pool, const char *imgname)
   if (r >= 0) {
     trim_image(pool, &header, 0);
     dout(2) << "\rremoving header..." << dendl;
-    rados.remove(pool, md_oid);
+    pool.remove(md_oid);
   }
 
   dout(2) << "removing rbd image to directory..." << dendl;
@@ -720,7 +701,7 @@ int remove(pool_t pool, const char *imgname)
   __u8 c = CEPH_OSD_TMAP_RM;
   ::encode(c, cmdbl);
   ::encode(imgname, cmdbl);
-  r = rados.tmap_update(pool, RBD_DIRECTORY, cmdbl);
+  r = pool.tmap_update(RBD_DIRECTORY, cmdbl);
   if (r < 0) {
     derr << "error removing img from directory: " << strerror(-r)<< dendl;
     return r;
@@ -736,7 +717,6 @@ int resize(ImageCtx *ictx, uint64_t size)
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
@@ -758,7 +738,7 @@ int resize(ImageCtx *ictx, uint64_t size)
   // rewrite header
   bufferlist bl;
   bl.append((const char *)&(ictx->header), sizeof(ictx->header));
-  r = rados.write(ictx->pool, md_oid, 0, bl, bl.length());
+  r = ictx->pool.write(md_oid, bl, bl.length(), 0);
   if (r == -ERANGE)
     derr << "operation might have conflicted with another client!" << dendl;
   if (r < 0) {
@@ -778,7 +758,6 @@ int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps)
   if (r < 0)
     return r;
   bufferlist bl, bl2;
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
@@ -798,11 +777,10 @@ int add_snap(ImageCtx *ictx, const char *snap_name)
 {
   bufferlist bl, bl2;
   uint64_t snap_id;
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
-  int r = rados.selfmanaged_snap_create(ictx->pool, &snap_id);
+  int r = ictx->pool.selfmanaged_snap_create(&snap_id);
   if (r < 0) {
     derr << "failed to create snap id: " << strerror(-r) << dendl;
     return r;
@@ -811,7 +789,7 @@ int add_snap(ImageCtx *ictx, const char *snap_name)
   ::encode(snap_name, bl);
   ::encode(snap_id, bl);
 
-  r = rados.exec(ictx->pool, md_oid, "rbd", "snap_add", bl, bl2);
+  r = ictx->pool.exec(md_oid, "rbd", "snap_add", bl, bl2);
   if (r < 0) {
     derr << "rbd.snap_add execution failed failed: " << strerror(-r) << dendl;
     return r;
@@ -821,13 +799,12 @@ int add_snap(ImageCtx *ictx, const char *snap_name)
   return 0;
 }
 
-int rm_snap(pool_t pool, string& md_oid, const char *snap_name)
+int rm_snap(PoolHandle& pool, string& md_oid, const char *snap_name)
 {
   bufferlist bl, bl2;
-  Rados rados(pool);
   ::encode(snap_name, bl);
 
-  int r = rados.exec(pool, md_oid, "rbd", "snap_remove", bl, bl2);
+  int r = pool.exec(md_oid, "rbd", "snap_remove", bl, bl2);
   if (r < 0) {
     derr << "rbd.snap_remove execution failed failed: " << strerror(-r) << dendl;
     return r;
@@ -851,14 +828,13 @@ int ictx_check(ImageCtx *ictx)
 int ictx_refresh(ImageCtx *ictx, const char *snap_name)
 {
   bufferlist bl, bl2;
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
   int r = read_header(ictx->pool, md_oid, &(ictx->header), NULL);
   if (r < 0)
     return r;
-  r = rados.exec(ictx->pool, md_oid, "rbd", "snap_list", bl, bl2);
+  r = ictx->pool.exec(md_oid, "rbd", "snap_list", bl, bl2);
   if (r < 0)
     return r;
 
@@ -904,7 +880,6 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name)
   int r = ictx_check(ictx);
   if (r < 0)
     return r;
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
@@ -912,11 +887,11 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name)
   if (r < 0)
     return r;
 
-  r = rados.set_snap_write_context(ictx->pool, ictx->snapc.seq, ictx->snaps);
+  r = ictx->pool.selfmanaged_snap_set_write_ctx(ictx->snapc.seq, ictx->snaps);
   if (r < 0)
     return r;
 
-  rados.set_snap_read(ictx->pool, ictx->snapid);
+  ictx->pool.snap_set_read(ictx->snapid);
   r = rollback_image(ictx, ictx->snapid);
   if (r < 0)
     return r;
@@ -924,13 +899,12 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name)
   return 0;
 }
 
-int copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *destname)
+int copy(PoolHandle& src_pool, const char *srcname, PoolHandle& dest_pool, const char *destname)
 {
   struct rbd_obj_header_ondisk header, dest_header;
   int64_t ret;
   int r;
   string md_oid, dest_md_oid;
-  Rados rados(src_pool);
   md_oid = srcname;
   md_oid += RBD_SUFFIX;
 
@@ -963,7 +937,7 @@ int copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *des
     string dest_oid = get_block_oid(&dest_header, i);
     map<off_t, size_t> m;
     map<off_t, size_t>::iterator iter;
-    r = rados.sparse_read(src_pool, oid, 0, block_size, m, bl);
+    r = src_pool.sparse_read(oid, m, bl, block_size, 0);
     if (r < 0 && r == -ENOENT)
       r = 0;
     if (r < 0)
@@ -979,7 +953,7 @@ int copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *des
        return -EIO;
       }
       bl.copy(extent_ofs, extent_len, wrbl);
-      r = rados.write(dest_pool, dest_oid, extent_ofs, wrbl, extent_len);
+      r = dest_pool.write(dest_oid, wrbl, extent_len, extent_ofs);
       if (r < 0)
        goto done;
     }
@@ -995,7 +969,6 @@ int snap_set(ImageCtx *ictx, const char *snap_name)
   int r = ictx_check(ictx);
   if (r < 0)
     return r;
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
@@ -1003,16 +976,16 @@ int snap_set(ImageCtx *ictx, const char *snap_name)
   if (r < 0)
     return r;
 
-  r = rados.set_snap_write_context(ictx->pool, ictx->snapc.seq, ictx->snaps);
+  r = ictx->pool.selfmanaged_snap_set_write_ctx(ictx->snapc.seq, ictx->snaps);
   if (r < 0)
     return r;
 
-  rados.set_snap_read(ictx->pool, ictx->snapid);
+  ictx->pool.snap_set_read(ictx->snapid);
 
   return 0;
 }
 
-int open_image(pool_t pool, ImageCtx *ictx, const char *name, const char *snap_name)
+int open_image(PoolHandle& pool, ImageCtx *ictx, const char *name, const char *snap_name)
 {
   int r = ictx_refresh(ictx, snap_name);
   if (r < 0)
@@ -1025,19 +998,17 @@ int open_image(pool_t pool, ImageCtx *ictx, const char *name, const char *snap_n
   string md_oid = name;
   md_oid += RBD_SUFFIX;
 
-  Rados rados(pool);
-  r = rados.watch(ictx->pool, md_oid, 0, &(wctx->cookie), wctx);
+  r = ictx->pool.watch(md_oid, 0, &(wctx->cookie), wctx);
   return r;
 }
 
 void close_image(ImageCtx *ictx)
 {
-  Rados rados(ictx->pool);
   string md_oid = ictx->name;
   md_oid += RBD_SUFFIX;
 
   ictx->wctx->invalidate();
-  rados.unwatch(ictx->pool, md_oid, ictx->wctx->cookie);
+  ictx->pool.unwatch(md_oid, ictx->wctx->cookie);
   delete ictx->wctx;
   delete ictx;
   ictx = NULL;
@@ -1051,7 +1022,6 @@ int read_iterate(ImageCtx *ictx, off_t off, size_t len,
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
   int64_t ret;
   int total_read = 0;
   uint64_t start_block = get_block_num(&ictx->header, off);
@@ -1068,7 +1038,7 @@ int read_iterate(ImageCtx *ictx, off_t off, size_t len,
     map<off_t, size_t> m;
     map<off_t, size_t>::iterator iter;
     off_t bl_ofs = 0, buf_bl_pos = 0;
-    r = rados.sparse_read(ictx->pool, oid, block_ofs, read_len, m, bl);
+    r = ictx->pool.sparse_read(oid, m, bl, read_len, block_ofs);
     if (r < 0 && r == -ENOENT)
       r = 0;
     if (r < 0) {
@@ -1138,7 +1108,6 @@ int write(ImageCtx *ictx, off_t off, size_t len, const char *buf)
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
   int total_write = 0;
   uint64_t start_block = get_block_num(&ictx->header, off);
   uint64_t end_block = get_block_num(&ictx->header, off + len - 1);
@@ -1151,7 +1120,7 @@ int write(ImageCtx *ictx, off_t off, size_t len, const char *buf)
     uint64_t block_ofs = get_block_ofs(&ictx->header, off + total_write);
     uint64_t write_len = min(block_size - block_ofs, left);
     bl.append(buf + total_write, write_len);
-    r = rados.write(ictx->pool, oid, block_ofs, bl, write_len);
+    r = ictx->pool.write(oid, bl, write_len, block_ofs);
     if (r < 0)
       return r;
     if ((uint64_t)r != write_len)
@@ -1246,7 +1215,6 @@ int aio_write(ImageCtx *ictx, off_t off, size_t len, const char *buf,
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
   int total_write = 0;
   uint64_t start_block = get_block_num(&ictx->header, off);
   uint64_t end_block = get_block_num(&ictx->header, off + len - 1);
@@ -1264,8 +1232,9 @@ int aio_write(ImageCtx *ictx, off_t off, size_t len, const char *buf,
     bl.append(buf + total_write, write_len);
     AioBlockCompletion *block_completion = new AioBlockCompletion(c, off, len, NULL);
     c->add_block_completion(block_completion);
-    librados::Rados::AioCompletion *rados_completion = rados.aio_create_completion(block_completion, NULL, rados_cb);
-    r = rados.aio_write(ictx->pool, oid, block_ofs, bl, write_len, rados_completion);
+    librados::AioCompletion *rados_completion =
+      Rados::aio_create_completion(block_completion, NULL, rados_cb);
+    r = ictx->pool.aio_write(oid, rados_completion, bl, write_len, block_ofs);
     if (r < 0)
       goto done;
     total_write += write_len;
@@ -1292,7 +1261,6 @@ int aio_read(ImageCtx *ictx, off_t off, size_t len,
   if (r < 0)
     return r;
 
-  Rados rados(ictx->pool);
   int64_t ret;
   int total_read = 0;
   uint64_t start_block = get_block_num(&ictx->header, off);
@@ -1312,10 +1280,11 @@ int aio_read(ImageCtx *ictx, off_t off, size_t len,
     AioBlockCompletion *block_completion = new AioBlockCompletion(c, block_ofs, read_len, buf + total_read);
     c->add_block_completion(block_completion);
 
-    librados::Rados::AioCompletion *rados_completion = rados.aio_create_completion(block_completion, rados_aio_sparse_read_cb, rados_cb);
-    r = rados.aio_sparse_read(ictx->pool, oid, block_ofs,
+    librados::AioCompletion *rados_completion =
+      Rados::aio_create_completion(block_completion, rados_aio_sparse_read_cb, rados_cb);
+    r = ictx->pool.aio_sparse_read(oid, rados_completion,
                              &block_completion->m, &block_completion->data_bl,
-                             read_len, rados_completion);
+                             read_len, block_ofs);
     if (r < 0 && r == -ENOENT)
       r = 0;
     if (r < 0) {
@@ -1346,7 +1315,7 @@ void librbd::RBD::version(int *major, int *minor, int *extra)
   rbd_version(major, minor, extra);
 }
 
-int librbd::RBD::open(pool_t pool, const char *name, image_t *image, const char *snap_name)
+int librbd::RBD::open(PoolHandle& pool, const char *name, image_t *image, const char *snap_name)
 {
   ImageCtx *ictx = new ImageCtx(name, pool);
   if (!ictx)
@@ -1363,7 +1332,7 @@ int librbd::RBD::close(image_t image)
   return 0; 
 }
 
-int librbd::RBD::create(pool_t pool, const char *name, size_t size, int *order)
+int librbd::RBD::create(PoolHandle& pool, const char *name, size_t size, int *order)
 {
   string md_oid = name;
   md_oid += RBD_SUFFIX;
@@ -1371,7 +1340,7 @@ int librbd::RBD::create(pool_t pool, const char *name, size_t size, int *order)
   return r;
 }
 
-int librbd::RBD::remove(pool_t pool, const char *name)
+int librbd::RBD::remove(PoolHandle& pool, const char *name)
 {
   int r = librbd::remove(pool, name);
   return r;
@@ -1391,19 +1360,19 @@ int librbd::RBD::stat(image_t image, image_info_t& info, size_t infosize)
   return r;
 }
 
-int librbd::RBD::list(pool_t pool, std::vector<std::string>& names)
+int librbd::RBD::list(PoolHandle& pool, std::vector<std::string>& names)
 {
   int r = librbd::list(pool, names);
   return r;
 }
 
-int librbd::RBD::copy(pool_t src_pool, const char *srcname, pool_t dest_pool, const char *destname)
+int librbd::RBD::copy(PoolHandle& src_pool, const char *srcname, PoolHandle& dest_pool, const char *destname)
 {
   int r = librbd::copy(src_pool, srcname, dest_pool, destname);
   return r;
 }
 
-int librbd::RBD::rename(pool_t src_pool, const char *srcname, const char *destname)
+int librbd::RBD::rename(PoolHandle& src_pool, const char *srcname, const char *destname)
 {
   int r = librbd::rename(src_pool, srcname, destname);
   return r;
@@ -1524,8 +1493,10 @@ extern "C" void rbd_version(int *major, int *minor, int *extra)
 }
 
 /* images */
-extern "C" int rbd_list(rados_pool_t pool, char *names, size_t *size)
+extern "C" int rbd_list(rados_pool_t p, char *names, size_t *size)
 {
+  librados::PoolHandle pool;
+  librados::PoolHandle::from_rados_pool_t(p, pool);
   std::vector<std::string> cpp_names;
   int r = librbd::list(pool, cpp_names);
   if (r == -ENOENT)
@@ -1551,30 +1522,41 @@ extern "C" int rbd_list(rados_pool_t pool, char *names, size_t *size)
   return (int)cpp_names.size();
 }
 
-extern "C" int rbd_create(rados_pool_t pool, const char *name, size_t size, int *order)
+extern "C" int rbd_create(rados_pool_t p, const char *name, size_t size, int *order)
 {
+  librados::PoolHandle pool;
+  librados::PoolHandle::from_rados_pool_t(p, pool);
   string md_oid = name;
   md_oid += RBD_SUFFIX;
   return librbd::create(pool, md_oid, name, size, order);
 }
 
-extern "C" int rbd_remove(rados_pool_t pool, const char *name)
+extern "C" int rbd_remove(rados_pool_t p, const char *name)
 {
+  librados::PoolHandle pool;
+  librados::PoolHandle::from_rados_pool_t(p, pool);
   return librbd::remove(pool, name);
 }
 
-extern "C" int rbd_copy(rados_pool_t src_pool, const char *srcname, rados_pool_t dest_pool, const char *destname)
+extern "C" int rbd_copy(rados_pool_t src_p, const char *srcname, rados_pool_t dest_p, const char *destname)
 {
+  librados::PoolHandle src_pool, dest_pool;
+  librados::PoolHandle::from_rados_pool_t(src_p, src_pool);
+  librados::PoolHandle::from_rados_pool_t(dest_p, dest_pool);
   return librbd::copy(src_pool, srcname, dest_pool, destname);
 }
 
-extern "C" int rbd_rename(rados_pool_t src_pool, const char *srcname, const char *destname)
+extern "C" int rbd_rename(rados_pool_t src_p, const char *srcname, const char *destname)
 {
+  librados::PoolHandle src_pool;
+  librados::PoolHandle::from_rados_pool_t(src_p, src_pool);
   return librbd::rename(src_pool, srcname, destname);
 }
 
-extern "C" int rbd_open(rados_pool_t pool, const char *name, rbd_image_t *image, const char *snap_name)
+extern "C" int rbd_open(rados_pool_t p, const char *name, rbd_image_t *image, const char *snap_name)
 {
+  librados::PoolHandle pool;
+  librados::PoolHandle::from_rados_pool_t(p, pool);
   librbd::ImageCtx *ictx = new librbd::ImageCtx(name, pool);
   if (!ictx)
     return -ENOMEM;
index 7b87eea1c400a596e3d9918d21cb3c4eca32614f..fc0421bccd0e5be35d7928f417837521dd194be3 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 -*-
 /*
  * Ceph - scalable distributed file system
  *
@@ -6,15 +6,15 @@
  *
  * 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.
- * 
+ *
  * Series of functions to test your rados installation. Notice
  * that this code is not terribly robust -- for instance, if you
  * try and bench on a pool you don't have permission to access
  * it will just loop forever.
  */
-#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
 #include "common/config.h"
 #include "common/common_init.h"
 #include "common/Cond.h"
@@ -59,15 +59,15 @@ void generate_object_name(char *s, int objnum, int pid = 0)
   }
 }
 
-int write_bench(Rados& rados, rados_pool_t pool,
+int write_bench(librados::Rados& rados, librados::PoolHandle& pool,
                 int secondsToRun, int concurrentios, bench_data *data);
-int seq_read_bench(Rados& rados, rados_pool_t pool,
+int seq_read_bench(librados::Rados& rados, librados::PoolHandle& pool,
                   int secondsToRun, int concurrentios, bench_data *data,
                   int writePid);
 void *status_printer(void * data_store);
 void sanitize_object_contents(bench_data *data, int length);
-  
-int aio_bench(Rados& rados, rados_pool_t pool, int operation,
+
+int aio_bench(librados::Rados& rados, librados::PoolHandle &pool, int operation,
              int secondsToRun, int concurrentios, int op_size) {
   int object_size = op_size;
   int num_objects = 0;
@@ -78,7 +78,7 @@ int aio_bench(Rados& rados, rados_pool_t pool, int operation,
   //get data from previous write run, if available
   if (operation != OP_WRITE) {
     bufferlist object_data;
-    r = rados.read(pool, BENCH_DATA, 0, object_data, sizeof(int)*3);
+    r = pool.read(BENCH_DATA, object_data, sizeof(int)*3, 0);
     if (r <= 0) {
       delete[] contentsChars;
       if (r == -2)
@@ -92,7 +92,7 @@ int aio_bench(Rados& rados, rados_pool_t pool, int operation,
   } else {
     object_size = op_size;
   }
-  
+
   dataLock.Lock();
   bench_data *data = new bench_data();
   data->done = false;
@@ -122,7 +122,7 @@ int aio_bench(Rados& rados, rados_pool_t pool, int operation,
     cerr << "Random test not implemented yet!" << std::endl;
     r = -1;
   }
-  
+
  out:
   delete[] contentsChars;
   delete data;
@@ -136,13 +136,13 @@ void _aio_cb(void *cb, void *arg) {
   dataLock.Unlock();
 }
 
-int write_bench(Rados& rados, rados_pool_t pool,
+int write_bench(librados::Rados& rados, librados::PoolHandle& pool,
                 int secondsToRun, int concurrentios, bench_data *data) {
   cout << "Maintaining " << concurrentios << " concurrent writes of "
        << data->object_size << " bytes for at least "
        << secondsToRun << " seconds." << std::endl;
-  
-  Rados::AioCompletion* completions[concurrentios];
+
+  librados::AioCompletion* completions[concurrentios];
   char* name[concurrentios];
   bufferlist* contents[concurrentios];
   double total_latency = 0;
@@ -164,7 +164,7 @@ int write_bench(Rados& rados, rados_pool_t pool,
   }
 
   pthread_t print_thread;
-  
+
   pthread_create(&print_thread, NULL, status_printer, (void *)data);
   dataLock.Lock();
   data->start_time = g_clock.now();
@@ -173,7 +173,7 @@ int write_bench(Rados& rados, rados_pool_t pool,
     start_times[i] = g_clock.now();
     completions[i] = rados.aio_create_completion((void *) &cond, 0,
                                                 &_aio_cb);
-    r = rados.aio_write(pool, name[i], 0, *contents[i], data->object_size, completions[i]);
+    r = pool.aio_write(name[i], completions[i], *contents[i], data->object_size, 0);
     if (r < 0) { //naughty, doesn't clean up heap
       goto ERR;
     }
@@ -182,14 +182,14 @@ int write_bench(Rados& rados, rados_pool_t pool,
     ++data->in_flight;
     dataLock.Unlock();
   }
-  
+
   //keep on adding new writes as old ones complete until we've passed minimum time
   int slot;
   bufferlist* newContents;
   char* newName;
-  
+
   //don't need locking for reads because other thread doesn't write
-  
+
   runtime.set_from_double(secondsToRun);
   stopTime = data->start_time + runtime;
   while( g_clock.now() < stopTime ) {
@@ -230,13 +230,12 @@ int write_bench(Rados& rados, rados_pool_t pool,
     completions[slot]->release();
     completions[slot] = 0;
     timePassed = g_clock.now() - data->start_time;
-    
+
     //write new stuff to rados, then delete old stuff
     //and save locations of new stuff for later deletion
     start_times[slot] = g_clock.now();
-    completions[slot] = rados.aio_create_completion((void *) &cond, 0, 
-                                                &_aio_cb);
-    r = rados.aio_write(pool, newName, 0, *newContents, data->object_size, completions[slot]);
+    completions[slot] = rados.aio_create_completion((void *) &cond, 0, &_aio_cb);
+    r = pool.aio_write(newName, completions[slot], *newContents, data->object_size, 0);
     if (r < 0) {//naughty; doesn't clean up heap space.
       goto ERR;
     }
@@ -285,7 +284,7 @@ int write_bench(Rados& rados, rados_pool_t pool,
   bandwidth = bandwidth/(1024*1024); // we want it in MB/sec
   char bw[20];
   snprintf(bw, sizeof(bw), "%.3lf \n", bandwidth);
-  
+
   cout << "Total time run:        " << timePassed << std::endl
        << "Total writes made:     " << data->finished << std::endl
        << "Write size:            " << data->object_size << std::endl
@@ -301,7 +300,7 @@ int write_bench(Rados& rados, rados_pool_t pool,
   ::encode(data->object_size, b_write);
   ::encode(data->finished, b_write);
   ::encode(getpid(), b_write);
-  rados.write(pool, BENCH_DATA, 0, b_write, sizeof(int)*3);
+  pool.write(BENCH_DATA, b_write, sizeof(int)*3, 0);
   return 0;
 
  ERR:
@@ -312,7 +311,7 @@ int write_bench(Rados& rados, rados_pool_t pool,
   return -5;
 }
 
-int seq_read_bench(Rados& rados, rados_pool_t pool, int seconds_to_run,
+int seq_read_bench(librados::Rados& rados, librados::PoolHandle& pool, int seconds_to_run,
                   int concurrentios, bench_data *write_data, int pid) {
   bench_data *data = new bench_data();
   data->done = false;
@@ -327,7 +326,7 @@ int seq_read_bench(Rados& rados, rados_pool_t pool, int seconds_to_run,
   data->object_contents = write_data->object_contents;
 
   Cond cond;
-  Rados::AioCompletion* completions[concurrentios];
+  librados::AioCompletion* completions[concurrentios];
   char* name[concurrentios];
   bufferlist* contents[concurrentios];
   int index[concurrentios];
@@ -360,9 +359,8 @@ int seq_read_bench(Rados& rados, rados_pool_t pool, int seconds_to_run,
   for (int i = 0; i < concurrentios; ++i) {
     index[i] = i;
     start_times[i] = g_clock.now();
-    completions[i] = rados.aio_create_completion((void *) &cond,
-                                                &_aio_cb, 0);
-    r = rados.aio_read(pool, name[i], 0, contents[i], data->object_size, completions[i]);
+    completions[i] = rados.aio_create_completion((void *) &cond, &_aio_cb, 0);
+    r = pool.aio_read(name[i], completions[i], contents[i], data->object_size, 0);
     if (r < 0) { //naughty, doesn't clean up heap -- oh, or handle the print thread!
       cerr << "r = " << r << std::endl;
       goto ERR;
@@ -419,9 +417,8 @@ int seq_read_bench(Rados& rados, rados_pool_t pool, int seconds_to_run,
     //start new read and check data if requested
     start_times[slot] = g_clock.now();
     contents[slot] = new bufferlist();
-    completions[slot] = rados.aio_create_completion((void *) &cond,
-                                                   &_aio_cb, 0);
-    r = rados.aio_read(pool, newName, 0, contents[slot], data->object_size, completions[slot]);
+    completions[slot] = rados.aio_create_completion((void *) &cond, &_aio_cb, 0);
+    r = pool.aio_read(newName, completions[slot], contents[slot], data->object_size, 0);
     if (r < 0) {
       goto ERR;
     }
@@ -521,8 +518,8 @@ void *status_printer(void * data_store) {
             << " max lat: " << data->max_latency
             << " avg lat: " << data->avg_latency << std::endl;
       //I'm naughty and don't reset the fill
-      cout << setfill(' ') 
-          << setw(5) << "sec" 
+      cout << setfill(' ')
+          << setw(5) << "sec"
           << setw(8) << "Cur ops"
           << setw(10) << "started"
           << setw(10) << "finished"
@@ -540,7 +537,7 @@ void *status_printer(void * data_store) {
     if (previous_writes != data->finished) {
       previous_writes = data->finished;
       cycleSinceChange = 0;
-      cout << setfill(' ') 
+      cout << setfill(' ')
           << setw(5) << i
           << setw(8) << data->in_flight
           << setw(10) << data->started
index 94a06ef4df888575349550478b8b8d21bb1450d5..b0f27fbbb8cca28d5fa8b764f53981f516a23591 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/types.h"
@@ -32,7 +32,7 @@ using namespace librados;
 #include <sstream>
 #include <errno.h>
 
-void usage() 
+void usage()
 {
   cerr << "usage: rados [options] [commands]" << std::endl;
   /*  cerr << "If no commands are specified, enter interactive mode.\n";
@@ -90,7 +90,7 @@ void usage()
 
 **********************************************/
 
-int main(int argc, const char **argv) 
+int main(int argc, const char **argv)
 {
   DEFINE_CONF_VARS(usage);
   vector<const char*> args;
@@ -103,19 +103,17 @@ int main(int argc, const char **argv)
   vector<const char*> nargs;
   bufferlist indata, outdata;
 
-  const char *pool = 0;
+  const char *pool_name = 0;
+
   int concurrent_ios = 16;
   int op_size = 1 << 22;
 
   const char *snapname = 0;
   snap_t snapid = CEPH_NOSNAP;
 
-  const char *filter = NULL;
-
   FOR_EACH_ARG(args) {
     if (CONF_ARG_EQ("pool", 'p')) {
-      CONF_SAFE_SET_ARG_VAL(&pool, OPT_STR);
+      CONF_SAFE_SET_ARG_VAL(&pool_name, OPT_STR);
     } else if (CONF_ARG_EQ("snapid", 'S')) {
       CONF_SAFE_SET_ARG_VAL(&snapid, OPT_LONGLONG);
     } else if (CONF_ARG_EQ("snap", 's')) {
@@ -126,8 +124,6 @@ int main(int argc, const char **argv)
       CONF_SAFE_SET_ARG_VAL(&concurrent_ios, OPT_INT);
     } else if (CONF_ARG_EQ("block-size", 'b')) {
       CONF_SAFE_SET_ARG_VAL(&op_size, OPT_INT);
-    } else if (CONF_ARG_EQ("filter", '\0')) {
-      CONF_SAFE_SET_ARG_VAL(&filter, OPT_STR);
     } else if (args[i][0] == '-' && nargs.empty()) {
       cerr << "unrecognized option " << args[i] << std::endl;
       usage();
@@ -140,40 +136,47 @@ int main(int argc, const char **argv)
 
   // open rados
   Rados rados;
-  if (rados.initialize(0, NULL) < 0) {
+  if (rados.init(NULL) < 0) {
      cerr << "couldn't initialize rados!" << std::endl;
      exit(1);
   }
 
+  if (rados.connect() < 0) {
+     cerr << "couldn't connect to cluster!" << std::endl;
+     exit(1);
+  }
+
   int ret = 0;
   char buf[80];
 
   // open pool?
-  pool_t p;
-  if (pool) {
-    ret = rados.open_pool(pool, &p);
+  PoolHandle pool;
+  if (pool_name) {
+    ret = rados.pool_open(pool_name, pool);
     if (ret < 0) {
-      cerr << "error opening pool " << pool << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto no_pool_out;
+      cerr << "error opening pool " << pool_name << ": "
+          << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
   }
 
   // snapname?
   if (snapname) {
-    ret = rados.snap_lookup(p, snapname, &snapid);
+    ret = pool.snap_lookup(snapname, &snapid);
     if (ret < 0) {
       cerr << "error looking up snap '" << snapname << "': " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      return 1;
     }
   }
   if (snapid != CEPH_NOSNAP) {
     string name;
-    ret = rados.snap_get_name(p, snapid, &name);
+    ret = pool.snap_get_name(snapid, &name);
     if (ret < 0) {
-      cerr << "snapid " << snapid << " doesn't exist in pool " << pool << std::endl;
-      goto out;
+      cerr << "snapid " << snapid << " doesn't exist in pool "
+          << pool.get_name() << std::endl;
+      return 1;
     }
-    rados.set_snap_read(p, snapid);
+    pool.snap_set_read(snapid);
     cout << "selected snap " << snapid << " '" << snapname << "'" << std::endl;
   }
 
@@ -188,9 +191,9 @@ int main(int argc, const char **argv)
     // pools
     list<string> vec;
     rados.pool_list(vec);
-    
+
     map<string,pool_stat_t> stats;
-    rados.pool_get_stats(vec, stats);
+    rados.get_pool_stats(vec, stats);
 
     printf("%-15s "
           "%12s %12s %12s %12s "
@@ -214,7 +217,7 @@ int main(int argc, const char **argv)
 
     // total
     statfs_t tstats;
-    rados.fs_get_stats(tstats);
+    rados.get_fs_stats(tstats);
     printf("  total used    %12lld %12lld\n", (long long unsigned)tstats.kb_used,
           (long long unsigned)tstats.num_objects);
     printf("  total avail   %12lld\n", (long long unsigned)tstats.kb_avail);
@@ -222,9 +225,9 @@ int main(int argc, const char **argv)
   }
 
   else if (strcmp(nargs[0], "ls") == 0) {
-    if (!pool) {
+    if (!pool_name) {
       cerr << "pool name was not specified" << std::endl;
-      goto out;
+      return 1;
     }
 
     bool stdout = (nargs.size() < 2) || (strcmp(nargs[1], "-") == 0);
@@ -234,89 +237,37 @@ int main(int argc, const char **argv)
     else
       outstream = new ofstream(nargs[1]);
 
-    Rados::ListCtx ctx;
-    rados.objects_list_open(p, &ctx);
-    bufferlist extra_info;
-    bool filter_parent = false;
-    if (filter) {
-      char *flt_str = strdup(filter);
-      char *type = strtok(flt_str, " ");
-      if (!type) {
-        cerr << "filter type was not specified" << std::endl;
-        goto out;
-      }
-      char *xattr = NULL;
-      if (strcmp(type, "parent") != 0)
-        xattr = strtok(NULL, " ");
-      char *val = strtok(NULL, " ");
-
-      if (!val) {
-        cerr << "filter was not specified correctly" << std::endl;
-        goto out;
-      }
-
-      bufferlist bl;
-      ::encode(type, bl);
-      if (strcmp(type, "parent") ==  0) {
-        inodeno_t int_val = strtoll(val, NULL, 0);
-        ::encode(int_val, bl);
-        filter_parent = true;
-      } else if (strcmp(type, "plain") == 0) {
-        ::encode(xattr, bl);
-        ::encode(val, bl);
-      } else {
-        cerr << "unknown filter type" << std::endl;
-        goto out;
+    {
+      librados::ObjectIterator i = pool.objects_begin();
+      librados::ObjectIterator i_end = pool.objects_end();
+      for (; i != i_end; ++i) {
+       *outstream << *i << std::endl;
       }
-
-      rados.list_filter(ctx, bl, &extra_info);
     }
-    while (1) {
-      list<string> vec;
-      ret = rados.objects_list_more(ctx, 1 << 10, vec);
-      if (ret < 0) {
-       cerr << "got error: " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-       delete outstream;
-       goto out;
-      }
-      if (vec.empty())
-       break;
-
-      bufferlist::iterator exiter = extra_info.begin();
-      for (list<string>::iterator iter = vec.begin(); iter != vec.end(); ++iter) {
-       *outstream << *iter << std::endl;
-        if (filter_parent) {
-          inode_backpointer_t backp;
-          ::decode(backp, exiter);
-          cout << " dirino=" << backp.dirino << " dname=" << backp.dname << " v=" << backp.version << std::endl;
-        }
-      }
-    }
-    rados.objects_list_close(ctx);
     if (!stdout)
       delete outstream;
   }
   else if (strcmp(nargs[0], "chown") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
 
     uint64_t new_auid = strtol(nargs[1], 0, 10);
-    ret = rados.change_pool_auid(p, new_auid);
+    ret = pool.set_auid(new_auid);
     if (ret < 0) {
-      cerr << "error changing auid on pool " << pool << ':'
+      cerr << "error changing auid on pool " << pool.get_name() << ':'
           << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-    } else cerr << "changed auid on pool " << pool
+    } else cerr << "changed auid on pool " << pool.get_name()
                << " to " << new_auid << std::endl;
   }
   else if (strcmp(nargs[0], "mapext") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
     string oid(nargs[1]);
     std::map<off_t, size_t> m;
-    ret = rados.mapext(p, oid, 0, -1, m);
+    ret = pool.mapext(oid, 0, -1, m);
     if (ret < 0) {
-      cerr << "mapext error on " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "mapext error on " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
     std::map<off_t, size_t>::iterator iter;
     for (iter = m.begin(); iter != m.end(); ++iter) {
@@ -324,13 +275,13 @@ int main(int argc, const char **argv)
     }
   }
   else if (strcmp(nargs[0], "get") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
     string oid(nargs[1]);
-    ret = rados.read(p, oid, 0, outdata, 0);
+    ret = pool.read(oid, outdata, 0, 0);
     if (ret < 0) {
-      cerr << "error reading " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error reading " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
 
     if (strcmp(nargs[2], "-") == 0) {
@@ -341,7 +292,7 @@ int main(int argc, const char **argv)
     }
   }
   else if (strcmp(nargs[0], "put") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
 
     string oid(nargs[1]);
@@ -360,7 +311,7 @@ int main(int argc, const char **argv)
       int fd = open(nargs[2], O_RDONLY);
       if (fd < 0) {
        cerr << "error reading input file " << nargs[2] << ": " << strerror_r(errno, buf, sizeof(buf)) << std::endl;
-       goto out;
+       return 1;
       }
       char buf[op_size];
       int count = op_size;
@@ -370,19 +321,19 @@ int main(int argc, const char **argv)
         if (count == 0)
           continue;
         indata.append(buf, count);
-        ret = rados.write(p, oid, offset, indata, count);
+        ret = pool.write(oid, indata, count, offset);
         indata.clear();
 
         if (ret < 0) {
-          cerr << "error writing " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-          goto out;
+          cerr << "error writing " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+         return 1;
         }
         offset += count;
       }
     }
   }
   else if (strcmp(nargs[0], "setxattr") == 0) {
-    if (!pool || nargs.size() < 4)
+    if (!pool_name || nargs.size() < 4)
       usage();
 
     string oid(nargs[1]);
@@ -392,50 +343,50 @@ int main(int argc, const char **argv)
     bufferlist bl;
     bl.append(attr_val.c_str(), attr_val.length());
 
-    ret = rados.setxattr(p, oid, attr_name.c_str(), bl);
+    ret = pool.setxattr(oid, attr_name.c_str(), bl);
     if (ret < 0) {
-      cerr << "error setting xattr " << pool << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error setting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
   }
   else if (strcmp(nargs[0], "getxattr") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
 
     string oid(nargs[1]);
     string attr_name(nargs[2]);
 
     bufferlist bl;
-    ret = rados.getxattr(p, oid, attr_name.c_str(), bl);
+    ret = pool.getxattr(oid, attr_name.c_str(), bl);
     if (ret < 0) {
-      cerr << "error getting xattr " << pool << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error getting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
     string s(bl.c_str(), bl.length());
     cout << s << std::endl;
   } else if (strcmp(nargs[0], "rmxattr") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
 
     string oid(nargs[1]);
     string attr_name(nargs[2]);
 
-    ret = rados.rmxattr(p, oid, attr_name.c_str());
+    ret = pool.rmxattr(oid, attr_name.c_str());
     if (ret < 0) {
-      cerr << "error removing xattr " << pool << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error removing xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
   } else if (strcmp(nargs[0], "listxattr") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
 
     string oid(nargs[1]);
     map<std::string, bufferlist> attrset;
     bufferlist bl;
-    ret = rados.getxattrs(p, oid, attrset);
+    ret = pool.getxattrs(oid, attrset);
     if (ret < 0) {
-      cerr << "error getting xattr set " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error getting xattr set " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
 
     for (map<std::string, bufferlist>::iterator iter = attrset.begin();
@@ -444,23 +395,23 @@ int main(int argc, const char **argv)
     }
   }
   else if (strcmp(nargs[0], "rm") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
     string oid(nargs[1]);
-    ret = rados.remove(p, oid);
+    ret = pool.remove(oid);
     if (ret < 0) {
-      cerr << "error removing " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error removing " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
   }
   else if (strcmp(nargs[0], "create") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
     string oid(nargs[1]);
-    ret = rados.create(p, oid, true);
+    ret = pool.create(oid, true);
     if (ret < 0) {
-      cerr << "error creating " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      cerr << "error creating " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+      return 1;
     }
   }
 
@@ -469,10 +420,10 @@ int main(int argc, const char **argv)
       usage();
     if (strcmp(nargs[1], "dump") == 0) {
       string oid(nargs[2]);
-      ret = rados.read(p, oid, 0, outdata, 0);
+      ret = pool.read(oid, outdata, 0, 0);
       if (ret < 0) {
-       cerr << "error reading " << pool << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-       goto out;
+       cerr << "error reading " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+       return 1;
       }
       bufferlist::iterator p = outdata.begin();
       bufferlist header;
@@ -488,7 +439,7 @@ int main(int argc, const char **argv)
        q->second.hexdump(cout);
        cout << "\n";
       }
-    }    
+    }
   }
 
   else if (strcmp(nargs[0], "mkpool") == 0) {
@@ -504,22 +455,21 @@ int main(int argc, const char **argv)
        cerr << "using crush rule " << (int)crush_rule << std::endl;
       }
     }
-    ret = rados.create_pool(nargs[1], auid, crush_rule);
+    ret = rados.pool_create(nargs[1], auid, crush_rule);
     if (ret < 0) {
       cerr << "error creating pool " << nargs[1] << ": "
           << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      return 1;
     }
     cout << "successfully created pool " << nargs[1] << std::endl;
   }
   else if (strcmp(nargs[0], "rmpool") == 0) {
     if (nargs.size() < 2)
       usage();
-    rados_pool_t rm_me;
-    ret = rados.open_pool(nargs[1], &rm_me);
+    librados::PoolHandle rm_me;
+    ret = rados.pool_open(nargs[1], rm_me);
     if (ret >= 0) {
-      ret = rados.delete_pool(rm_me);
-      if (ret < 0) {
+      if (rm_me.destroy() < 0) {
        cerr << "error deleting pool " << nargs[1] << ": "
             << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
       }
@@ -529,19 +479,19 @@ int main(int argc, const char **argv)
     }
   }
   else if (strcmp(nargs[0], "lssnap") == 0) {
-    if (!pool || nargs.size() != 1)
+    if (!pool_name || nargs.size() != 1)
       usage();
 
     vector<snap_t> snaps;
-    rados.snap_list(p, &snaps);
+    pool.snap_list(&snaps);
     for (vector<snap_t>::iterator i = snaps.begin();
         i != snaps.end();
         i++) {
       string s;
       time_t t;
-      if (rados.snap_get_name(p, *i, &s) < 0)
+      if (pool.snap_get_name(*i, &s) < 0)
        continue;
-      if (rados.snap_get_stamp(p, *i, &t) < 0)
+      if (pool.snap_get_stamp(*i, &t) < 0)
        continue;
       struct tm bdt;
       localtime_r(&t, &bdt);
@@ -563,47 +513,47 @@ int main(int argc, const char **argv)
   }
 
   else if (strcmp(nargs[0], "mksnap") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
-    
-    ret = rados.snap_create(p, nargs[1]);
+
+    ret = pool.snap_create(nargs[1]);
     if (ret < 0) {
-      cerr << "error creating pool " << pool << " snapshot " << nargs[1]
+      cerr << "error creating pool " << pool_name << " snapshot " << nargs[1]
           << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      return 1;
     }
-    cout << "created pool " << pool << " snap " << nargs[1] << std::endl;
+    cout << "created pool " << pool_name << " snap " << nargs[1] << std::endl;
   }
 
   else if (strcmp(nargs[0], "rmsnap") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool_name || nargs.size() < 2)
       usage();
-    
-    ret = rados.snap_remove(p, nargs[1]);
+
+    ret = pool.snap_remove(nargs[1]);
     if (ret < 0) {
-      cerr << "error removing pool " << pool << " snapshot " << nargs[1]
+      cerr << "error removing pool " << pool_name << " snapshot " << nargs[1]
           << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      return 1;
     }
-    cout << "removed pool " << pool << " snap " << nargs[1] << std::endl;
+    cout << "removed pool " << pool_name << " snap " << nargs[1] << std::endl;
   }
 
   else if (strcmp(nargs[0], "rollback") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
 
-    ret = rados.snap_rollback_object(p, nargs[1], nargs[2]);
+    ret = pool.rollback(nargs[1], nargs[2]);
     if (ret < 0) {
-      cerr << "error rolling back pool " << pool << " to snapshot " << nargs[1] 
+      cerr << "error rolling back pool " << pool_name << " to snapshot " << nargs[1]
           << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
-      goto out;
+      return 1;
     }
-    cout << "rolled back pool " << pool
+    cout << "rolled back pool " << pool_name
         << " to snapshot " << nargs[2] << std::endl;
   }
-  
+
   else if (strcmp(nargs[0], "bench") == 0) {
-    if (!pool || nargs.size() < 3)
+    if (!pool_name || nargs.size() < 3)
       usage();
     int seconds = atoi(nargs[1]);
     int operation = 0;
@@ -615,7 +565,7 @@ int main(int argc, const char **argv)
       operation = OP_RAND_READ;
     else
       usage();
-    ret = aio_bench(rados, p, operation, seconds, concurrent_ios, op_size);
+    ret = aio_bench(rados, pool, operation, seconds, concurrent_ios, op_size);
     if (ret != 0)
       cerr << "error during benchmark: " << ret << std::endl;
   }
@@ -624,14 +574,6 @@ int main(int argc, const char **argv)
     usage();
   }
 
- out:
-  if (pool)
-    rados.close_pool(p);
-
- no_pool_out:
-  rados.shutdown();
-  if (ret < 0)
-    return 1;
-  return 0;
+  return (ret < 0) ? 1 : 0;
 }
 
index 36ad761413d456e8f9b95a368a322eeb569bf95e..d7645ebf1ffbfcb047e76ecef407eab83f1860ee 100644 (file)
@@ -124,10 +124,14 @@ void get_user(ACLID& aclid, ACLEntity *entity)
 int main(int argc, const char **argv) 
 {
   Rados rados;
-  if (rados.initialize(0, NULL) < 0) {
+  if (rados.init(NULL) < 0) {
      cerr << "couldn't initialize rados!" << std::endl;
      exit(1);
   }
+  if (rados.connect() < 0) {
+     cerr << "couldn't connect to cluster!" << std::endl;
+     exit(1);
+  }
 
   time_t tm;
   bufferlist bl, bl2;
@@ -139,16 +143,16 @@ int main(int argc, const char **argv)
 
   const char *oid = "bar";
 
-  pool_t pool;
-  int r = rados.open_pool("data", &pool);
-  cout << "open pool result = " << r << " pool = " << pool << std::endl;
+  PoolHandle pool;
+  int r = rados.pool_open("data", pool);
+  cout << "open pool result = " << r << " pool = " << pool.get_name() << std::endl;
 
   ACLID id;
 
   snprintf(id.id, ID_SIZE + 1, "%.16x", 0x1234);
   cout << "id=" << id.id << std::endl;
 
-  r = rados.exec(pool, oid, "acl", "get", bl, bl2);
+  r = pool.exec(oid, "acl", "get", bl, bl2);
   cout << "exec returned " << r << " len=" << bl2.length() << std::endl;
   ObjectACLs oa;
   if (r >= 0) {
@@ -159,14 +163,14 @@ int main(int argc, const char **argv)
   oa.set_acl(id, ACL_RD);
   bl.clear();
   oa.encode(bl);
-  r = rados.exec(pool, oid, "acl", "set", bl, bl2);
+  r = pool.exec(oid, "acl", "set", bl, bl2);
 
   const unsigned char *md5 = (const unsigned char *)bl2.c_str();
   char md5_str[bl2.length()*2 + 1];
   buf_to_hex(md5, bl2.length(), md5_str);
   cout << "md5 result=" << md5_str << std::endl;
 
-  int size = rados.read(pool, oid, 0, bl2, 128);
+  int size = pool.read(oid, bl2, 128, 0);
   cout << "read result=" << bl2.c_str() << std::endl;
   cout << "size=" << size << std::endl;
 
index 327fd32a31b10ac82ce7b03b39b9c8b8af3e094d..9d48aa7631ee7c4a1fe217ae1c234a85538b0e1c 100644 (file)
@@ -100,7 +100,7 @@ static void print_info(const char *imgname, librbd::image_info_t& info)
        << std::endl;
 }
 
-static int do_list(librados::pool_t pool)
+static int do_list(librados::PoolHandle& pool)
 {
   std::vector<string> names;
   int r = rbd.list(pool, names);
@@ -112,7 +112,7 @@ static int do_list(librados::pool_t pool)
   return 0;
 }
 
-static int do_create(librados::pool_t pool, const char *imgname, size_t size, int *order)
+static int do_create(librados::PoolHandle& pool, const char *imgname, size_t size, int *order)
 {
   int r = rbd.create(pool, imgname, size, order);
   if (r < 0)
@@ -120,7 +120,7 @@ static int do_create(librados::pool_t pool, const char *imgname, size_t size, in
   return 0;
 }
 
-static int do_rename(librados::pool_t pool, const char *imgname, const char *destname)
+static int do_rename(librados::PoolHandle& pool, const char *imgname, const char *destname)
 {
   int r = rbd.rename(pool, imgname, destname);
   if (r < 0)
@@ -139,7 +139,7 @@ static int do_show_info(const char *imgname, librbd::image_t image)
   return 0;
 }
 
- static int do_delete(librados::pool_t pool, const char *imgname)
+ static int do_delete(librados::PoolHandle& pool, const char *imgname)
 {
   int r = rbd.remove(pool, imgname);
   if (r < 0)
@@ -308,7 +308,7 @@ done_img:
   update_snap_name(*new_img, snap);
 }
 
-static int do_import(librados::pool_t pool, const char *imgname, int *order, const char *path)
+static int do_import(librados::PoolHandle& pool, const char *imgname, int *order, const char *path)
 {
   int fd = open(path, O_RDONLY);
   int r;
@@ -446,7 +446,7 @@ done:
   return r;
 }
 
-static int do_copy(librados::pool_t& pp, const char *imgname, librados::pool_t& dest_pp, const char *destname)
+static int do_copy(librados::PoolHandle& pp, const char *imgname, librados::PoolHandle& dest_pp, const char *destname)
 {
   int r = rbd.copy(pp, imgname, dest_pp, destname);
   if (r < 0)
@@ -454,7 +454,7 @@ static int do_copy(librados::pool_t& pp, const char *imgname, librados::pool_t&
   return 0;
 }
 
-class RbdWatchCtx : public librados::Rados::WatchCtx {
+class RbdWatchCtx : public librados::WatchCtx {
   string name;
 public:
   RbdWatchCtx(const char *imgname) : name(imgname) {}
@@ -464,7 +464,7 @@ public:
   }
 };
 
-static int do_watch(librados::pool_t& pp, const char *imgname)
+static int do_watch(librados::PoolHandle& pp, const char *imgname)
 {
   string md_oid, dest_md_oid;
   uint64_t cookie;
@@ -473,7 +473,7 @@ static int do_watch(librados::pool_t& pp, const char *imgname)
   md_oid = imgname;
   md_oid += RBD_SUFFIX;
 
-  int r = rados.watch(pp, md_oid, 0, &cookie, &ctx);
+  int r = pp.watch(md_oid, 0, &cookie, &ctx);
   if (r < 0) {
     cerr << "watch failed" << std::endl;
     return r;
@@ -485,11 +485,11 @@ static int do_watch(librados::pool_t& pp, const char *imgname)
   return 0;
 }
 
-static void err_exit(librados::pool_t pool, librbd::image_t image = NULL)
+static void err_exit(librados::PoolHandle& pool, librbd::image_t image = NULL)
 {
   if (image)
     rbd.close(image);
-  rados.close_pool(pool);
+  pool.close();
   rados.shutdown();
   exit(1);
 }
@@ -679,7 +679,7 @@ int main(int argc, const char **argv)
   if (!dest_poolname)
     dest_poolname = poolname;
 
-  librados::pool_t pool, dest_pool;
+  librados::PoolHandle pool, dest_pool;
   librbd::image_t image = NULL;
 
   if (opt_cmd == OPT_EXPORT && !path)
@@ -690,14 +690,18 @@ int main(int argc, const char **argv)
     usage_exit();
   }
 
-  if (rados.initialize(NULL, 0) < 0) {
+  if (rados.init(NULL) < 0) {
     cerr << "error: couldn't initialize rados!" << std::endl;
     exit(1);
   }
 
-  // TODO: add argc/argv conf
-  
-  int r = rados.open_pool(poolname, &pool);
+  if (rados.connect() < 0) {
+    cerr << "error: couldn't connect to the cluster!" << std::endl;
+    exit(1);
+  }
+
+  // TODO: add conf
+  int r = rados.pool_open(poolname, pool);
   if (r < 0) {
       cerr << "error opening pool " << poolname << " (err=" << r << ")" << std::endl;
       err_exit(pool);
@@ -723,7 +727,7 @@ int main(int argc, const char **argv)
   }
 
   if (opt_cmd == OPT_COPY || opt_cmd == OPT_IMPORT) {
-    r = rados.open_pool(dest_poolname, &dest_pool);
+    r = rados.pool_open(dest_poolname, dest_pool);
     if (r < 0) {
       cerr << "error opening pool " << dest_poolname << " (err=" << r << ")" << std::endl;
       err_exit(pool);
@@ -887,7 +891,8 @@ int main(int argc, const char **argv)
   if (image)
     rbd.close(image);
 
-  rados.close_pool(pool);
+  pool.close();
+  dest_pool.close();
   rados.shutdown();
   return 0;
 }
index b594502e4ed23edf15a036365142b8fe60027552..00dd09604936837d71bd78fbb0ebf07992872f90 100644 (file)
@@ -20,7 +20,7 @@ Rados *rados = NULL;
 #define ROOT_BUCKET ".rgw" //keep this synced to rgw_user.cc::root_bucket!
 
 static string root_bucket(ROOT_BUCKET);
-static rados_pool_t root_pool;
+static librados::PoolHandle root_pool;
 
 /** 
  * Initialize the RADOS instance and prepare to do other ops
@@ -28,15 +28,20 @@ static rados_pool_t root_pool;
  */
 int RGWRados::initialize(int argc, char *argv[])
 {
+  int ret;
   rados = new Rados();
   if (!rados)
     return -ENOMEM;
 
-  int ret = rados->initialize(argc, (const char **)argv);
+  ret = rados->init(NULL);
   if (ret < 0)
    return ret;
 
-  ret = open_root_pool(&root_pool);
+  ret = rados->connect();
+  if (ret < 0)
+   return ret;
+
+  ret = open_root_pool();
 
   return ret;
 }
@@ -45,15 +50,15 @@ int RGWRados::initialize(int argc, char *argv[])
  * Open the pool used as root for this gateway
  * Returns: 0 on success, -ERR# otherwise.
  */
-int RGWRados::open_root_pool(rados_pool_t *pool)
+int RGWRados::open_root_pool()
 {
-  int r = rados->open_pool(root_bucket.c_str(), pool);
-  if (r < 0) {
-    r = rados->create_pool(root_bucket.c_str());
+  int r = rados->pool_open(root_bucket.c_str(), root_pool);
+  if (r == -ENOENT) {
+    r = rados->pool_create(root_bucket.c_str());
     if (r < 0)
       return r;
 
-    r = rados->open_pool(root_bucket.c_str(), pool);
+    r = rados->pool_open(root_bucket.c_str(), root_pool);
   }
 
   return r;
@@ -113,15 +118,6 @@ int RGWRados::list_buckets_next(std::string& id, RGWObjEnt& obj, RGWAccessHandle
   return 0;
 }
 
-static int open_pool(string& bucket, rados_pool_t *pool)
-{
-  return rados->open_pool(bucket.c_str(), pool);
-}
-
-static int close_pool(rados_pool_t pool)
-{
-  return rados->close_pool(pool);
-}
 /** 
  * get listing of the objects in a bucket.
  * id: ignored.
@@ -139,31 +135,21 @@ static int close_pool(rados_pool_t pool)
 int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix, string& delim,
                           string& marker, vector<RGWObjEnt>& result, map<string, bool>& common_prefixes)
 {
-  rados_pool_t pool;
-  set<string> dir_set;
-
-  int r = rados->open_pool(bucket.c_str(), &pool);
+  librados::PoolHandle pool;
+  int r = rados->pool_open(bucket.c_str(), pool);
   if (r < 0)
     return r;
 
-
-#define MAX_ENTRIES 1000
-  Rados::ListCtx ctx;
-  rados->objects_list_open(pool, &ctx);
-  do {
-    list<string> entries;
-    r = rados->objects_list_more(ctx, MAX_ENTRIES, entries);
-    if (r < 0)
-      return r;
-
-    for (list<string>::iterator iter = entries.begin(); iter != entries.end(); ++iter) {
-      if (prefix.empty() ||
-          (iter->compare(0, prefix.size(), prefix) == 0)) {
-        dir_set.insert(*iter);
-      }
+  set<string> dir_set;
+  {
+    librados::ObjectIterator i_end = pool.objects_end();
+    for (librados::ObjectIterator i = pool.objects_begin(); i != i_end; ++i) {
+       if (prefix.empty() ||
+           ((*i).compare(0, prefix.size(), prefix) == 0)) {
+         dir_set.insert(*i);
+       }
     }
-  } while (r);
-  rados->objects_list_close(ctx);
+  }
 
   set<string>::iterator p;
   if (!marker.empty())
@@ -191,19 +177,18 @@ int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix,
     }
 
     uint64_t s;
-    if (rados->stat(pool, *p, &s, &obj.mtime) < 0)
+    if (pool.stat(*p, &s, &obj.mtime) < 0)
       continue;
     obj.size = s;
 
     bufferlist bl; 
     obj.etag[0] = '\0';
-    if (rados->getxattr(pool, *p, RGW_ATTR_ETAG, bl) >= 0) {
+    if (pool.getxattr(*p, RGW_ATTR_ETAG, bl) >= 0) {
       strncpy(obj.etag, bl.c_str(), sizeof(obj.etag));
       obj.etag[sizeof(obj.etag)-1] = '\0';
     }
     result.push_back(obj);
   }
-  rados->close_pool(pool);
 
   return count;
 }
@@ -215,7 +200,7 @@ int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix,
  */
 int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid)
 {
-  int ret = rados->create(root_pool, bucket, true);
+  int ret = root_pool.create(bucket, true);
   if (ret < 0)
     return ret;
 
@@ -225,7 +210,7 @@ int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::strin
     bufferlist& bl = iter->second;
     
     if (bl.length()) {
-      ret = rados->setxattr(root_pool, bucket, name.c_str(), bl);
+      ret = root_pool.setxattr(bucket, name.c_str(), bl);
       if (ret < 0) {
         delete_bucket(id, bucket);
         return ret;
@@ -233,7 +218,7 @@ int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::strin
     }
   }
 
-  ret = rados->create_pool(bucket.c_str(), auid);
+  ret = rados->pool_create(bucket.c_str(), auid);
 
   return ret;
 }
@@ -252,9 +237,9 @@ int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::strin
 int RGWRados::put_obj_meta(std::string& id, std::string& bucket, std::string& oid,
                   time_t *mtime, map<string, bufferlist>& attrs)
 {
-  rados_pool_t pool;
+  librados::PoolHandle pool;
 
-  int r = open_pool(bucket, &pool);
+  int r = rados->pool_open(bucket.c_str(), pool);
   if (r < 0)
     return r;
 
@@ -264,20 +249,18 @@ int RGWRados::put_obj_meta(std::string& id, std::string& bucket, std::string& oi
     bufferlist& bl = iter->second;
 
     if (bl.length()) {
-      r = rados->setxattr(pool, oid, name.c_str(), bl);
+      r = pool.setxattr(oid, name.c_str(), bl);
       if (r < 0)
         return r;
     }
   }
 
   if (mtime) {
-    r = rados->stat(pool, oid, NULL, mtime);
+    r = pool.stat(oid, NULL, mtime);
     if (r < 0)
       return r;
   }
 
-  close_pool(pool);
-
   return 0;
 }
 
@@ -295,26 +278,24 @@ int RGWRados::put_obj_meta(std::string& id, std::string& bucket, std::string& oi
 int RGWRados::put_obj_data(std::string& id, std::string& bucket, std::string& oid, const char *data, off_t ofs, size_t len,
                   time_t *mtime)
 {
-  rados_pool_t pool;
+  librados::PoolHandle pool;
 
-  int r = open_pool(bucket, &pool);
+  int r = rados->pool_open(bucket.c_str(), pool);
   if (r < 0)
     return r;
 
   bufferlist bl;
   bl.append(data, len);
-  r = rados->write(pool, oid, ofs, bl, len);
+  r = pool.write(oid, bl, len, ofs);
   if (r < 0)
     return r;
 
   if (mtime) {
-    r = rados->stat(pool, oid, NULL, mtime);
+    r = pool.stat(oid, NULL, mtime);
     if (r < 0)
       return r;
   }
 
-  close_pool(pool);
-
   return 0;
 }
 /**
@@ -394,15 +375,16 @@ done_err:
  */
 int RGWRados::delete_bucket(std::string& id, std::string& bucket)
 {
-  rados_pool_t pool;
-
-  int r = open_pool(bucket, &pool);
-  if (r < 0) return r;
-
-  r = rados->delete_pool(pool);
-  if (r < 0) return r;
-  r = delete_obj(id, root_bucket, bucket);
-  return r;
+  int ret;
+  librados::PoolHandle pool;
+  ret = rados->pool_open(bucket.c_str(), pool);
+  if (ret < 0)
+    return ret;
+  ret = pool.destroy();
+  if (ret)
+    return ret;
+  ret = delete_obj(id, root_bucket, bucket);
+  return ret;
 }
 
 /**
@@ -414,13 +396,12 @@ int RGWRados::delete_bucket(std::string& id, std::string& bucket)
  */
 int RGWRados::delete_obj(std::string& id, std::string& bucket, std::string& oid)
 {
-  rados_pool_t pool;
-
-  int r = open_pool(bucket, &pool);
+  librados::PoolHandle pool;
+  int r = rados->pool_open(bucket.c_str(), pool);
   if (r < 0)
     return r;
 
-  r = rados->remove(pool, oid);
+  r = pool.remove(oid);
   if (r < 0)
     return r;
 
@@ -438,7 +419,7 @@ int RGWRados::delete_obj(std::string& id, std::string& bucket, std::string& oid)
 int RGWRados::get_attr(std::string& bucket, std::string& obj,
                        const char *name, bufferlist& dest)
 {
-  rados_pool_t pool;
+  librados::PoolHandle pool;
   string actual_bucket = bucket;
   string actual_obj = obj;
 
@@ -447,12 +428,11 @@ int RGWRados::get_attr(std::string& bucket, std::string& obj,
     actual_bucket = root_bucket;
   }
 
-  int r = open_pool(actual_bucket, &pool);
+  int r = rados->pool_open(actual_bucket.c_str(), pool);
   if (r < 0)
     return r;
 
-  r = rados->getxattr(pool, actual_obj, name, dest);
-
+  r = pool.getxattr(actual_obj, name, dest);
   if (r < 0)
     return r;
 
@@ -470,7 +450,7 @@ int RGWRados::get_attr(std::string& bucket, std::string& obj,
 int RGWRados::set_attr(std::string& bucket, std::string& oid,
                        const char *name, bufferlist& bl)
 {
-  rados_pool_t pool;
+  librados::PoolHandle pool;
   string actual_bucket = bucket;
   string actual_obj = oid;
 
@@ -479,12 +459,11 @@ int RGWRados::set_attr(std::string& bucket, std::string& oid,
     actual_bucket = root_bucket;
   }
 
-  int r = open_pool(actual_bucket, &pool);
+  int r = rados->pool_open(actual_bucket.c_str(), pool);
   if (r < 0)
     return r;
 
-  r = rados->setxattr(pool, actual_obj, name, bl);
-
+  r = pool.setxattr(actual_obj, name, bl);
   if (r < 0)
     return r;
 
@@ -542,16 +521,16 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid,
 
   *handle = state;
 
-  r = open_pool(bucket, &state->pool);
+  r = rados->pool_open(bucket.c_str(), state->pool);
   if (r < 0)
     goto done_err;
 
-  r = rados->stat(state->pool, oid, &size, &mtime);
+  r = state->pool.stat(oid, &size, &mtime);
   if (r < 0)
     goto done_err;
 
   if (attrs) {
-    r = rados->getxattrs(state->pool, oid, *attrs);
+    r = state->pool.getxattrs(oid, *attrs);
     if (rgw_log_level >= 20) {
       for (iter = attrs->begin(); iter != attrs->end(); ++iter) {
         RGW_LOG(20) << "Read xattr: " << iter->first << endl;
@@ -639,7 +618,7 @@ int RGWRados::get_obj(void **handle,
     len = RGW_MAX_CHUNK_SIZE;
 
   RGW_LOG(20) << "rados->read ofs=" << ofs << " len=" << len << endl;
-  int r = rados->read(state->pool, oid, ofs, bl, len);
+  int r = state->pool.read(oid, bl, len, ofs);
   RGW_LOG(20) << "rados->read r=" << r << endl;
 
   if (r > 0) {
@@ -648,7 +627,6 @@ int RGWRados::get_obj(void **handle,
   }
 
   if (r < 0 || !len || ((off_t)(ofs + len - 1) == end)) {
-    rados->close_pool(state->pool);
     delete state;
     *handle = NULL;
   }
@@ -661,7 +639,6 @@ void RGWRados::finish_get_obj(void **handle)
 {
   if (*handle) {
     GetObjState *state = *(GetObjState **)handle;
-    rados->close_pool(state->pool);
     delete state;
     *handle = NULL;
   }
index 18ad044fb34216b091f0a2a745a65ebb97c536e9..09b4505a4c8e4bdf04ae9ee627881ef77a527ce3 100644 (file)
@@ -1,20 +1,20 @@
 #ifndef CEPH_RGWRADOS_H
 #define CEPH_RGWRADOS_H
 
-#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
 #include "rgw_access.h"
 #include "rgw_common.h"
 
 class RGWRados  : public RGWAccess
 {
   /** Open the pool used as root for this gateway */
-  int open_root_pool(rados_pool_t *pool);
+  int open_root_pool();
 
   struct GetObjState {
-    rados_pool_t pool;
+    librados::PoolHandle pool;
     bool sent_data;
 
-    GetObjState() : pool(0), sent_data(false) {}
+    GetObjState() : sent_data(false) {}
   };
 
 public:
index 814a4f5db915f5032cfa0c72e0462c15aef85084..ef8e40d573b82b4866b0abae8a19a1fb2b7b3838 100644 (file)
@@ -33,7 +33,7 @@ typename T::iterator rand_choose(T &cont)
 
 struct TestOp
 {
-  librados::Rados::AioCompletion *completion;
+  librados::AioCompletion *completion;
   bool done;
   virtual void begin() = 0;
 
index ab199db3126462700767cda643afc4761e25ba8c..a2c7e016eba3824a4f95f404b8aa36357345feed 100644 (file)
@@ -288,6 +288,6 @@ int main(int argc, const char **argv)
   test_delete(pool, TEST_IMAGE "1");
   test_ls(pool, 0);
   rados_pool_close(pool);
-  rados_destroy(cluster);
+  rados_shutdown(cluster);
   return 0;
 }
index 7ee3cae4620ac04d829e2e7af826a41ce7903754..0599d42447481682783b2773f25575652e1ea41a 100644 (file)
@@ -188,7 +188,7 @@ int main(int argc, const char **argv)
   printf("rados_delete_pool = %d\n", r);  
   r = rados_pool_close(pool);
 
-  rados_destroy(cl);
+  rados_shutdown(cl);
 
   return 0;
 }
index e358664ed5fb327f969e444546122e55f96dfd56..253f8ccfc44cd9ab247240b2bd14ffc77143bf4b 100644 (file)
@@ -30,7 +30,7 @@ void buf_to_hex(const unsigned char *buf, int len, char *str)
   }
 }
 
-class C_Watch : public Rados::WatchCtx {
+class C_Watch : public WatchCtx {
 public:
   C_Watch() {}
   void notify(uint8_t opcode, uint64_t ver) {
@@ -41,11 +41,41 @@ public:
 int main(int argc, const char **argv) 
 {
   Rados rados;
-  if (rados.initialize(argc, argv) < 0) {
+  if (rados.init(NULL) < 0) {
      cerr << "couldn't initialize rados!" << std::endl;
      exit(1);
   }
 
+  if (rados.conf_read_file("/etc/ceph/ceph.conf")) {
+     cerr << "couldn't read configuration file." << std::endl;
+     exit(1);
+  }
+
+  if (!rados.conf_set("config option that doesn't exist",
+                     "some random value")) {
+    printf("error: succeeded in setting nonexistent config option\n");
+    exit(1);
+  }
+  if (rados.conf_set(cl, "log to stderr", "2")) {
+    printf("error: error setting log_to_stderr\n");
+    exit(1);
+  }
+  rados.reopen_log();
+  std::string tmp;
+  if (rados.conf_get("log to stderr", tmp)) {
+    printf("error: failed to read log_to_stderr from config\n");
+    exit(1);
+  }
+  if (tmp[0] != '2') {
+    printf("error: new setting for log_to_stderr failed to take effect.\n");
+    exit(1);
+  }
+
+  if (rados.connect()) {
+    printf("error connecting\n");
+    exit(1);
+  }
+
   cout << "rados_initialize completed" << std::endl;
   cout << "*** press enter to continue ***" << std::endl;
   getchar();
@@ -61,9 +91,8 @@ int main(int argc, const char **argv)
 
   const char *oid = "bar";
 
-  pool_t pool;
-
-  int r = rados.open_pool("data", &pool);
+  PoolHandle pool;
+  int r = rados.pool_open("data", &pool);
   cout << "open pool result = " << r << " pool = " << pool << std::endl;
 
   r = rados.write(pool, oid, 0, bl, bl.length());