]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librados_test_stub: support AIO snapshot context
authorJason Dillaman <dillaman@redhat.com>
Mon, 20 Apr 2015 16:12:05 +0000 (12:12 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 7 May 2015 02:07:46 +0000 (22:07 -0400)
AIO operations can be executed with a different snapshot
context from the IoCtx.  librbd takes advantage of this
capability to perform a deep object copyup.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/librados_test_stub/LibradosTestStub.cc
src/test/librados_test_stub/TestClassHandler.cc
src/test/librados_test_stub/TestClassHandler.h
src/test/librados_test_stub/TestIoCtxImpl.cc
src/test/librados_test_stub/TestIoCtxImpl.h
src/test/librados_test_stub/TestMemIoCtxImpl.cc
src/test/librados_test_stub/TestMemIoCtxImpl.h

index fb0812043b724a2dec03b67d6210981a164ae63c..4e1c0075ae76d703c4fb6cf67070df8b18b8b98a 100644 (file)
@@ -395,7 +395,8 @@ void IoCtx::dup(const IoCtx& rhs) {
 int IoCtx::exec(const std::string& oid, const char *cls, const char *method,
                 bufferlist& inbl, bufferlist& outbl) {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
-  return ctx->exec(oid, *get_class_handler(), cls, method, inbl, &outbl);
+  return ctx->exec(oid, *get_class_handler(), cls, method, inbl, &outbl,
+                   ctx->get_snap_context());
 }
 
 void IoCtx::from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) {
@@ -548,12 +549,12 @@ int IoCtx::watch2(const std::string& o, uint64_t *handle,
 int IoCtx::write(const std::string& oid, bufferlist& bl, size_t len,
                  uint64_t off) {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
-  return ctx->write(oid, bl, len, off);
+  return ctx->write(oid, bl, len, off, ctx->get_snap_context());
 }
 
 int IoCtx::write_full(const std::string& oid, bufferlist& bl) {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
-  return ctx->write_full(oid, bl);
+  return ctx->write_full(oid, bl, ctx->get_snap_context());
 }
 
 static int save_operation_result(int result, int *pval) {
@@ -587,7 +588,7 @@ void ObjectOperation::exec(const char *cls, const char *method,
   TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
   o->ops.push_back(boost::bind(&TestIoCtxImpl::exec, _1, _2,
                               boost::ref(*get_class_handler()),
-                              cls, method, inbl, _3));
+                              cls, method, inbl, _3, _4));
 }
 
 void ObjectOperation::set_op_flags2(int flags) {
@@ -605,7 +606,7 @@ void ObjectReadOperation::list_snaps(snap_set_t *out_snaps, int *prval) {
                                            out_snaps);
   if (prval != NULL) {
     op = boost::bind(save_operation_result,
-                     boost::bind(op, _1, _2, _3), prval);
+                     boost::bind(op, _1, _2, _3, _4), prval);
   }
   o->ops.push_back(op);
 }
@@ -623,7 +624,7 @@ void ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl,
 
   if (prval != NULL) {
     op = boost::bind(save_operation_result,
-                     boost::bind(op, _1, _2, _3), prval);
+                     boost::bind(op, _1, _2, _3, _4), prval);
   }
   o->ops.push_back(op);
 }
@@ -642,7 +643,7 @@ void ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
 
   if (prval != NULL) {
     op = boost::bind(save_operation_result,
-                     boost::bind(op, _1, _2, _3), prval);
+                     boost::bind(op, _1, _2, _3, _4), prval);
   }
   o->ops.push_back(op);
 }
@@ -683,12 +684,12 @@ void ObjectWriteOperation::truncate(uint64_t off) {
 void ObjectWriteOperation::write(uint64_t off, const bufferlist& bl) {
   TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
   o->ops.push_back(boost::bind(&TestIoCtxImpl::write, _1, _2, bl, bl.length(),
-                              off));
+                              off, _4));
 }
 
 void ObjectWriteOperation::write_full(const bufferlist& bl) {
   TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
-  o->ops.push_back(boost::bind(&TestIoCtxImpl::write_full, _1, _2, bl));
+  o->ops.push_back(boost::bind(&TestIoCtxImpl::write_full, _1, _2, bl, _4));
 }
 
 void ObjectWriteOperation::zero(uint64_t off, uint64_t len) {
@@ -990,13 +991,13 @@ int cls_cxx_write(cls_method_context_t hctx, int ofs, int len,
                   bufferlist *inbl) {
   librados::TestClassHandler::MethodContext *ctx =
     reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
-  return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs);
+  return ctx->io_ctx_impl->write(ctx->oid, *inbl, len, ofs, ctx->snapc);
 }
 
 int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl) {
   librados::TestClassHandler::MethodContext *ctx =
     reinterpret_cast<librados::TestClassHandler::MethodContext*>(hctx);
-  return ctx->io_ctx_impl->write_full(ctx->oid, *inbl);
+  return ctx->io_ctx_impl->write_full(ctx->oid, *inbl, ctx->snapc);
 }
 
 int cls_log(int level, const char *format, ...) {
index c7a2e96fd8874685b6eeb36e17df588eac0bfa34..e55770f4e43f50dd80dfb4da4e519549c03495eb 100644 (file)
@@ -100,10 +100,12 @@ cls_method_cxx_call_t TestClassHandler::get_method(const std::string &cls,
 }
 
 TestClassHandler::SharedMethodContext TestClassHandler::get_method_context(
-    TestIoCtxImpl *io_ctx_impl, const std::string &oid) {
+    TestIoCtxImpl *io_ctx_impl, const std::string &oid,
+    const SnapContext &snapc) {
   SharedMethodContext ctx(new MethodContext());
   ctx->io_ctx_impl = io_ctx_impl;
   ctx->oid = oid;
+  ctx->snapc = snapc;
   return ctx;
 }
 
index d921d418463e2d2dcdd0ff9112848b680ab99a6f..97062cec6917b325c349f9d9bfb092be7e8216a8 100644 (file)
@@ -5,6 +5,7 @@
 #define CEPH_TEST_CLASS_HANDLER_H
 
 #include "objclass/objclass.h"
+#include "common/snap_types.h"
 #include <boost/shared_ptr.hpp>
 #include <list>
 #include <map>
@@ -24,6 +25,7 @@ public:
   struct MethodContext {
     TestIoCtxImpl *io_ctx_impl;
     std::string oid;
+    SnapContext snapc;
   };
   typedef boost::shared_ptr<MethodContext> SharedMethodContext;
 
@@ -47,7 +49,8 @@ public:
   cls_method_cxx_call_t get_method(const std::string &cls,
                                    const std::string &method);
   SharedMethodContext get_method_context(TestIoCtxImpl *io_ctx_impl,
-                                         const std::string &oid);
+                                         const std::string &oid,
+                                         const SnapContext &snapc);
 
 private:
 
index f810906a19e645aed340ce888dccaae4a6aa05bd..36be941bdef23dc3a89ecb32d4c4258370754e02 100644 (file)
@@ -88,11 +88,12 @@ void TestIoCtxImpl::aio_flush_async(AioCompletionImpl *c) {
 int TestIoCtxImpl::aio_operate(const std::string& oid, TestObjectOperationImpl &ops,
                                AioCompletionImpl *c, SnapContext *snap_context,
                                int flags) {
-  // TODO ignoring snap_context and flags for now
+  // TODO flags for now
   ops.get();
   m_client->add_aio_operation(oid, true, boost::bind(
     &TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
-    reinterpret_cast<bufferlist*>(NULL)), c);
+    reinterpret_cast<bufferlist*>(NULL),
+    snap_context != NULL ? *snap_context : m_snapc), c);
   return 0;
 }
 
@@ -103,20 +104,21 @@ int TestIoCtxImpl::aio_operate_read(const std::string& oid,
   // TODO ignoring flags for now
   ops.get();
   m_client->add_aio_operation(oid, true, boost::bind(
-    &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl), c);
+    &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl, m_snapc), c);
   return 0;
 }
 
 int TestIoCtxImpl::exec(const std::string& oid, TestClassHandler &handler,
                         const char *cls, const char *method,
-                        bufferlist& inbl, bufferlist* outbl) {
+                        bufferlist& inbl, bufferlist* outbl,
+                        const SnapContext &snapc) {
   cls_method_cxx_call_t call = handler.get_method(cls, method);
   if (call == NULL) {
     return -ENOSYS;
   }
 
   return (*call)(reinterpret_cast<cls_method_context_t>(
-    handler.get_method_context(this, oid).get()), &inbl, outbl);
+    handler.get_method_context(this, oid, snapc).get()), &inbl, outbl);
 }
 
 int TestIoCtxImpl::list_watchers(const std::string& o,
@@ -141,7 +143,7 @@ int TestIoCtxImpl::operate(const std::string& oid, TestObjectOperationImpl &ops)
   ops.get();
   m_client->add_aio_operation(oid, false, boost::bind(
     &TestIoCtxImpl::execute_aio_operations, this, oid, &ops,
-    reinterpret_cast<bufferlist*>(NULL)), comp);
+    reinterpret_cast<bufferlist*>(NULL), m_snapc), comp);
 
   comp->wait_for_safe();
   int ret = comp->get_return_value();
@@ -155,7 +157,8 @@ int TestIoCtxImpl::operate_read(const std::string& oid, TestObjectOperationImpl
 
   ops.get();
   m_client->add_aio_operation(oid, false, boost::bind(
-    &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl), comp);
+    &TestIoCtxImpl::execute_aio_operations, this, oid, &ops, pbl,
+    m_snapc), comp);
 
   comp->wait_for_complete();
   int ret = comp->get_return_value();
@@ -229,7 +232,7 @@ int TestIoCtxImpl::tmap_update(const std::string& oid, bufferlist& cmdbl) {
   bufferlist out;
   ::encode(tmap_header, out);
   ::encode(tmap, out);
-  r = write_full(oid, out);
+  r = write_full(oid, out, m_snapc);
   return r;
 }
 
@@ -244,10 +247,12 @@ int TestIoCtxImpl::watch(const std::string& o, uint64_t *handle,
 
 int TestIoCtxImpl::execute_aio_operations(const std::string& oid,
                                           TestObjectOperationImpl *ops,
-                                          bufferlist *pbl) {
+                                          bufferlist *pbl,
+                                          const SnapContext &snapc) {
   int ret = 0;
-  for (ObjectOperations::iterator it = ops->ops.begin(); it != ops->ops.end(); ++it) {
-    ret = (*it)(this, oid, pbl);
+  for (ObjectOperations::iterator it = ops->ops.begin();
+       it != ops->ops.end(); ++it) {
+    ret = (*it)(this, oid, pbl, snapc);
     if (ret < 0) {
       break;
     }
index d21fd667c05eb40e5a30c2ca60cc7d8d9bb83b63..9c4e98067c909510cecbb781f00fef36c7677302 100644 (file)
@@ -18,7 +18,8 @@ class TestRadosClient;
 
 typedef boost::function<int(TestIoCtxImpl*,
                            const std::string&,
-                           bufferlist *)> ObjectOperationTestImpl;
+                           bufferlist *,
+                            const SnapContext &)> ObjectOperationTestImpl;
 typedef std::list<ObjectOperationTestImpl> ObjectOperations;
 
 struct TestObjectOperationImpl {
@@ -74,7 +75,8 @@ public:
   virtual int create(const std::string& oid, bool exclusive) = 0;
   virtual int exec(const std::string& oid, TestClassHandler &handler,
                    const char *cls, const char *method,
-                   bufferlist& inbl, bufferlist* outbl);
+                   bufferlist& inbl, bufferlist* outbl,
+                   const SnapContext &snapc);
   virtual int list_snaps(const std::string& o, snap_set_t *out_snaps) = 0;
   virtual int list_watchers(const std::string& o,
                             std::list<obj_watch_t> *out_watchers);
@@ -117,8 +119,9 @@ public:
   virtual int watch(const std::string& o, uint64_t *handle,
                     librados::WatchCtx *ctx, librados::WatchCtx2 *ctx2);
   virtual int write(const std::string& oid, bufferlist& bl, size_t len,
-                    uint64_t off) = 0;
-  virtual int write_full(const std::string& oid, bufferlist& bl) = 0;
+                    uint64_t off, const SnapContext &snapc) = 0;
+  virtual int write_full(const std::string& oid, bufferlist& bl,
+                         const SnapContext &snapc) = 0;
   virtual int xattr_get(const std::string& oid,
                         std::map<std::string, bufferlist>* attrset) = 0;
   virtual int xattr_set(const std::string& oid, const std::string &name,
@@ -129,8 +132,9 @@ protected:
   TestIoCtxImpl(const TestIoCtxImpl& rhs);
   virtual ~TestIoCtxImpl();
 
-  int execute_aio_operations(const std::string& oid, TestObjectOperationImpl *ops,
-                             bufferlist *pbl);
+  int execute_aio_operations(const std::string& oid,
+                             TestObjectOperationImpl *ops,
+                             bufferlist *pbl, const SnapContext &snapc);
 
 private:
 
index 2e6518a174efe85b79854732a4c927471b1c61ae..e35416399974f86dafc41a5dbb8a5dc3c02b740b 100644 (file)
@@ -45,7 +45,8 @@ int TestMemIoCtxImpl::aio_remove(const std::string& oid, AioCompletionImpl *c) {
 
 int TestMemIoCtxImpl::assert_exists(const std::string &oid) {
   RWLock::RLocker l(m_pool->file_lock);
-  TestMemRadosClient::SharedFile file = get_file(oid, false);
+  TestMemRadosClient::SharedFile file = get_file(oid, false,
+                                                 get_snap_context());
   if (file == NULL) {
     return -ENOENT;
   }
@@ -58,7 +59,7 @@ int TestMemIoCtxImpl::create(const std::string& oid, bool exclusive) {
   }
 
   RWLock::WLocker l(m_pool->file_lock);
-  get_file(oid, true);
+  get_file(oid, true, get_snap_context());
   return 0;
 }
 
@@ -140,7 +141,7 @@ int TestMemIoCtxImpl::omap_get_vals(const std::string& oid,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::RLocker l(m_pool->file_lock);
-    file = get_file(oid, false);
+    file = get_file(oid, false, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -180,7 +181,7 @@ int TestMemIoCtxImpl::omap_rm_keys(const std::string& oid,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true);
+    file = get_file(oid, true, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -203,7 +204,7 @@ int TestMemIoCtxImpl::omap_set(const std::string& oid,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true);
+    file = get_file(oid, true, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -225,7 +226,7 @@ int TestMemIoCtxImpl::read(const std::string& oid, size_t len, uint64_t off,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::RLocker l(m_pool->file_lock);
-    file = get_file(oid, false);
+    file = get_file(oid, false, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -250,11 +251,12 @@ int TestMemIoCtxImpl::remove(const std::string& oid) {
   }
 
   RWLock::WLocker l(m_pool->file_lock);
-  TestMemRadosClient::SharedFile file = get_file(oid, false);
+  TestMemRadosClient::SharedFile file = get_file(oid, false,
+                                                 get_snap_context());
   if (file == NULL) {
     return -ENOENT;
   }
-  file = get_file(oid, true);
+  file = get_file(oid, true, get_snap_context());
 
   RWLock::WLocker l2(file->lock);
   file->exists = false;
@@ -340,7 +342,7 @@ int TestMemIoCtxImpl::sparse_read(const std::string& oid, uint64_t off,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::RLocker l(m_pool->file_lock);
-    file = get_file(oid, false);
+    file = get_file(oid, false, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -367,7 +369,7 @@ int TestMemIoCtxImpl::stat(const std::string& oid, uint64_t *psize,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::RLocker l(m_pool->file_lock);
-    file = get_file(oid, false);
+    file = get_file(oid, false, get_snap_context());
     if (file == NULL) {
       return -ENOENT;
     }
@@ -391,7 +393,7 @@ int TestMemIoCtxImpl::truncate(const std::string& oid, uint64_t size) {
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true);
+    file = get_file(oid, true, get_snap_context());
   }
 
   RWLock::WLocker l(file->lock);
@@ -419,7 +421,7 @@ int TestMemIoCtxImpl::truncate(const std::string& oid, uint64_t size) {
 }
 
 int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
-                            uint64_t off) {
+                            uint64_t off, const SnapContext &snapc) {
   if (get_snap_read() != CEPH_NOSNAP) {
     return -EROFS;
   }
@@ -427,7 +429,7 @@ int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true);
+    file = get_file(oid, true, snapc);
   }
 
   RWLock::WLocker l(file->lock);
@@ -443,7 +445,8 @@ int TestMemIoCtxImpl::write(const std::string& oid, bufferlist& bl, size_t len,
   return 0;
 }
 
-int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl) {
+int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl,
+                                 const SnapContext &snapc) {
   if (get_snap_read() != CEPH_NOSNAP) {
     return -EROFS;
   }
@@ -451,7 +454,7 @@ int TestMemIoCtxImpl::write_full(const std::string& oid, bufferlist& bl) {
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, true);
+    file = get_file(oid, true, snapc);
     if (file == NULL) {
       return -ENOENT;
     }
@@ -494,11 +497,11 @@ int TestMemIoCtxImpl::zero(const std::string& oid, uint64_t off, uint64_t len) {
   TestMemRadosClient::SharedFile file;
   {
     RWLock::WLocker l(m_pool->file_lock);
-    file = get_file(oid, false);
+    file = get_file(oid, false, get_snap_context());
     if (!file) {
       return 0;
     }
-    file = get_file(oid, true);
+    file = get_file(oid, true, get_snap_context());
 
     RWLock::RLocker l2(file->lock);
     if (len > 0 && off + len >= file->data.length()) {
@@ -512,7 +515,7 @@ int TestMemIoCtxImpl::zero(const std::string& oid, uint64_t off, uint64_t len) {
 
   bufferlist bl;
   bl.append_zero(len);
-  return write(oid, bl, len, off);
+  return write(oid, bl, len, off, get_snap_context());
 }
 
 void TestMemIoCtxImpl::append_clone(bufferlist& src, bufferlist* dest) {
@@ -544,7 +547,7 @@ void TestMemIoCtxImpl::ensure_minimum_length(size_t len, bufferlist *bl) {
 }
 
 TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
-    const std::string &oid, bool write) {
+    const std::string &oid, bool write, const SnapContext &snapc) {
   assert(m_pool->file_lock.is_locked() || m_pool->file_lock.is_wlocked());
   assert(!write || m_pool->file_lock.is_wlocked());
 
@@ -557,7 +560,6 @@ TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
   }
 
   if (write) {
-    const SnapContext &snapc = get_snap_context();
     bool new_version = false;
     if (!file || !file->exists) {
       file = TestMemRadosClient::SharedFile(new TestMemRadosClient::File());
@@ -572,11 +574,13 @@ TestMemRadosClient::SharedFile TestMemIoCtxImpl::get_file(
           }
         }
 
-        uint64_t prev_size = file->data.length();
+        bufferlist prev_data = file->data;
         file = TestMemRadosClient::SharedFile(
           new TestMemRadosClient::File(*file));
-        if (prev_size > 0) {
-          file->snap_overlap.insert(0, prev_size);
+        file->data.clear();
+        append_clone(prev_data, &file->data);
+        if (prev_data.length() > 0) {
+          file->snap_overlap.insert(0, prev_data.length());
         }
         new_version = true;
       }
index 68adf2105e0be010de9c2d67af9fac26edee64e3..bde6ba0ed5f6e344148502a2f5f371044b98e648 100644 (file)
@@ -45,8 +45,9 @@ public:
   virtual int stat(const std::string& oid, uint64_t *psize, time_t *pmtime);
   virtual int truncate(const std::string& oid, uint64_t size);
   virtual int write(const std::string& oid, bufferlist& bl, size_t len,
-                    uint64_t off);
-  virtual int write_full(const std::string& oid, bufferlist& bl);
+                    uint64_t off, const SnapContext &snapc);
+  virtual int write_full(const std::string& oid, bufferlist& bl,
+                         const SnapContext &snapc);
   virtual int xattr_get(const std::string& oid,
                         std::map<std::string, bufferlist>* attrset);
   virtual int xattr_set(const std::string& oid, const std::string &name,
@@ -63,7 +64,8 @@ private:
   size_t clip_io(size_t off, size_t len, size_t bl_len);
   void ensure_minimum_length(size_t len, bufferlist *bl);
 
-  TestMemRadosClient::SharedFile get_file(const std::string &oid, bool write);
+  TestMemRadosClient::SharedFile get_file(const std::string &oid, bool write,
+                                          const SnapContext &snapc);
 
 };