]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_test_rados_api_aio: test pool EIO flag
authorSage Weil <sage@newdream.net>
Wed, 15 Sep 2021 23:06:27 +0000 (19:06 -0400)
committerSage Weil <sage@newdream.net>
Mon, 27 Sep 2021 17:20:31 +0000 (13:20 -0400)
Signed-off-by: Sage Weil <sage@newdream.net>
src/test/librados/aio_cxx.cc

index 9f27c61833f669e0dc8724f1bd819fde5078d031..28360b3d93833f73e2ffb905d89d965fa221f018 100644 (file)
@@ -13,6 +13,7 @@
 #include "include/types.h"
 #include "include/stringify.h"
 #include "include/scope_guard.h"
+#include "common/ceph_mutex.h"
 
 #include "test_cxx.h"
 
@@ -2230,3 +2231,90 @@ TEST(LibRadosAio, RoundTripCmpExtPP2)
   ioctx.remove("test_obj");
   destroy_one_pool_pp(pool_name, cluster);
 }
+
+ceph::mutex my_lock = ceph::make_mutex("my_lock");
+set<unsigned> inflight;
+unsigned max_success = 0;
+unsigned min_failed = 0;
+
+struct io_info {
+  unsigned i;
+  AioCompletion *c;
+};
+
+void pool_io_callback(completion_t cb, void *arg)
+{
+  AioCompletion *c = (AioCompletion*)cb;
+  io_info *info = (io_info *)arg;
+  unsigned long i = info->i;
+  int r = info->c->get_return_value();
+  //cout << "finish " << i << " r = " << r << std::endl;
+
+  std::scoped_lock l(my_lock);
+  inflight.erase(i);
+  if (r == 0) {
+    if (i > max_success) {
+      max_success = i;
+    }
+  } else {
+    if (!min_failed || i < min_failed) {
+      min_failed = i;
+    }
+  }
+}
+
+TEST(LibRadosAio, PoolEIOFlag) {
+  AioTestDataPP test_data;
+  ASSERT_EQ("", test_data.init());
+
+  bufferlist bl;
+  bl.append("some data");
+  std::thread *t = nullptr;
+  
+  unsigned max = 100;
+  unsigned long i = 1;
+  my_lock.lock();
+  for (; min_failed == 0; ++i) {
+    io_info *info = new io_info;
+    info->i = i;
+    info->c = Rados::aio_create_completion();
+    info->c->set_complete_callback((void*)info, pool_io_callback);
+    inflight.insert(i);
+    my_lock.unlock();
+    int r = test_data.m_ioctx.aio_write("foo", info->c, bl, bl.length(), 0);
+    //cout << "start " << i << " r = " << r << std::endl;
+
+    if (i == max / 2) {
+      cout << "setting pool EIO" << std::endl;
+      t = new std::thread(
+       [&] {
+         bufferlist empty;
+         int r = test_data.m_cluster.mon_command(
+           "{\"prefix\": \"osd pool set\", \"pool\": \"" + test_data.m_pool_name +
+           "\", \"var\": \"eio\", \"val\": \"true\"}", empty, nullptr, nullptr);
+         ceph_assert(r == 0);
+       });
+    }
+
+    sleep(.01);
+    my_lock.lock();
+    if (r < 0) {
+      inflight.erase(i);
+      break;
+    }
+  }
+  t->join();
+  delete t;
+
+  // wait for ios to finish
+  for (; !inflight.empty(); ++i) {
+    cout << "waiting for " << inflight << std::endl;
+    my_lock.unlock();
+    sleep(1);
+    my_lock.lock();
+  }
+
+  cout << "max_success " << max_success << ", min_failed " << min_failed << std::endl;
+  ASSERT_TRUE(max_success + 1 == min_failed);
+  my_lock.unlock();
+}