mock osd Journal and FileStore




最近在分析ceph rbd性能瓶颈,想排除掉磁盘对性能的影响,单独分析osd层软件栈的耗时,因此想mock掉所有落盘的代码,测试了下可以实现。

代码是基于H版本0.94.6修改的,仅供参考。patch如下,代码不多,不做解释了:

diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index 0748acf..7255f53 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -858,6 +858,7 @@ OPTION(filestore_fd_cache_shards, OPT_INT, 16)   // FD number of shards
 OPTION(filestore_dump_file, OPT_STR, "")         // file onto which store transaction dumps
 OPTION(filestore_kill_at, OPT_INT, 0)            // inject a failure at the n'th opportunity
 OPTION(filestore_inject_stall, OPT_INT, 0)       // artificially stall for N seconds in op queue thread
+OPTION(filestore_inject_blackhole, OPT_BOOL, false)
 OPTION(filestore_fail_eio, OPT_BOOL, true)       // fail/crash on EIO
 OPTION(filestore_debug_verify_split, OPT_BOOL, false)
 OPTION(journal_dio, OPT_BOOL, true)
diff --git a/src/os/FileJournal.cc b/src/os/FileJournal.cc
index 14cecc2..ce8da41 100644
--- a/src/os/FileJournal.cc
+++ b/src/os/FileJournal.cc
@@ -1370,7 +1370,10 @@ int FileJournal::write_aio_bl(off64_t& pos, bufferlist& bl, uint64_t seq)
     iocb *piocb = &aio.iocb;
     int attempts = 10;
     do {
-      int r = io_submit(aio_ctx, 1, &piocb);
+      int r = 1;
+      if (!g_conf->filestore_inject_blackhole) {
+          r = io_submit(aio_ctx, 1, &piocb);
+      }
       if (r < 0) {
        derr << "io_submit to " << aio.off << "~" << aio.len
             << " got " << cpp_strerror(r) << dendl;
@@ -1406,7 +1409,10 @@ void FileJournal::write_finish_thread_entry()

     dout(20) << "write_finish_thread_entry waiting for aio(s)" << dendl;
     io_event event[16];
-    int r = io_getevents(aio_ctx, 1, 16, event, NULL);
+    int r = 1;
+    if (!g_conf->filestore_inject_blackhole) {
+        r = io_getevents(aio_ctx, 1, 16, event, NULL);
+    }
     if (r < 0) {
       if (r == -EINTR) {
        dout(0) << "io_getevents got " << cpp_strerror(r) << dendl;
@@ -1416,6 +1422,7 @@ void FileJournal::write_finish_thread_entry()
       assert(0 == "got unexpected error from io_getevents");
     }

+    if (!g_conf->filestore_inject_blackhole)
     {
       Mutex::Locker locker(aio_lock);
       for (int i=0; i<r ; i++) {
@@ -1449,6 +1456,9 @@ void FileJournal::write_finish_thread_entry()
        ai->done = true;
       }
       check_aio_completion();
+    } else {
+        Mutex::Locker locker(aio_lock);
+        check_aio_completion();
     }
   }
   dout(10) < < "write_finish_thread_entry exit" << dendl;
@@ -1468,7 +1478,7 @@ void FileJournal::check_aio_completion()
   uint64_t new_journaled_seq = 0;

   list<aio_info>::iterator p = aio_queue.begin();
-  while (p != aio_queue.end() && p->done) {
+  while (p != aio_queue.end() && (p->done || g_conf->filestore_inject_blackhole)) {
     dout(20) < < "check_aio_completion completed seq " << p->seq < < " "
             << p->off < < "~" << p->len < < dendl;
     if (p->seq) {
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index 3e7e8fb..4c59040 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -2286,7 +2286,8 @@ unsigned FileStore::_do_transaction(

     Transaction::Op *op = i.decode_op();
     int r = 0;
-
+    if (g_conf->filestore_inject_blackhole)
+        return 0;
     _inject_failure();

     switch (op->op) {