]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
test/librados/aio_cxx: skip EIO boundary assertion when no in-flight I/Os
authorNitzan Mordechai <nmordech@redhat.com>
Wed, 7 May 2025 13:37:34 +0000 (13:37 +0000)
committerNitzan Mordechai <nmordech@redhat.com>
Sun, 29 Jun 2025 06:24:05 +0000 (06:24 +0000)
In the PoolEIOFlag test we now track whether any async writes were still
in flight at the moment we flipped the pool’s `eio=true` flag using an
atomic `missed_eio` flag set inside the helper thread.  If we never
actually overlapped any in-flight AIOs (we completed all aio successfully)
with the flag flip, we `GTEST_SKIP()` the final `max_success+1 == min_failed`
boundary assertion, avoiding spurious failures when all writes complete
before EIO takes effect.

Fixes: https://tracker.ceph.com/issues/70852
Signed-off-by: Nitzan Mordechai <nmordech@redhat.com>
(cherry picked from commit 07319d9a37ef70b6422e26eba8a251f711db2c6b)

src/test/librados/aio_cxx.cc

index 5e35869b5c2f3ffc8fd5885000f568097a8745cf..b0b7b6c4e7d50d806ee5e44c937dc9658c893c87 100644 (file)
@@ -1,6 +1,8 @@
+#include <common/dout.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <deque>
+#include <iostream>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -2347,7 +2349,7 @@ void pool_io_callback(completion_t cb, void *arg /* Actually AioCompletion* */)
     ASSERT_EQ(0, info->c->wait_for_complete());
   }
   int r = info->c->get_return_value();
-  //cout << "finish " << i << " r = " << r << std::endl;
+  cout << "finish " << i << " r = " << r << std::endl;
 
   std::scoped_lock l(my_lock);
   inflight.erase(i);
@@ -2369,8 +2371,9 @@ TEST(LibRadosAio, PoolEIOFlag) {
   bufferlist bl;
   bl.append("some data");
   std::thread *t = nullptr;
+  std::atomic<bool> missed_eio{false};
   
-  unsigned max = 100;
+  unsigned max = 1000;
   unsigned timeout = max * 10;
   unsigned long i = 1;
   my_lock.lock();
@@ -2385,19 +2388,23 @@ TEST(LibRadosAio, PoolEIOFlag) {
     //cout << "start " << i << " r = " << r << std::endl;
 
     if (i == max / 2) {
-      cout << "setting pool EIO" << std::endl;
-      t = new std::thread(
-       [&] {
-         bufferlist empty;
-         ASSERT_EQ(0, test_data.m_cluster.mon_command(
-           fmt::format(R"({{
-                       "prefix": "osd pool set",
-                       "pool": "{}",
-                       "var": "eio",
-                       "val": "true"
-                       }})", test_data.m_pool_name),
-           empty, nullptr, nullptr));
-       });
+      t = new std::thread([&] {
+        bufferlist empty;
+        cout << "sending pool EIO time: " << ceph_clock_now() << std::endl;
+        ASSERT_EQ(0, test_data.m_cluster.mon_command(
+          fmt::format(R"({{
+            "prefix": "osd pool set",
+            "pool": "{}",
+            "var": "eio",
+            "val": "true"
+            }})", test_data.m_pool_name),
+       empty, nullptr, nullptr));
+
+        {
+          std::scoped_lock lk(my_lock);
+          missed_eio = (!min_failed && max_success == max);
+        }
+      });
     }
 
     std::this_thread::sleep_for(10ms);
@@ -2418,6 +2425,10 @@ TEST(LibRadosAio, PoolEIOFlag) {
     my_lock.lock();
   }
 
+  if (!missed_eio) {
+    GTEST_SKIP() << "eio flag missed all ios that already completed";
+    my_lock.unlock();
+  }
   cout << "max_success " << max_success << ", min_failed " << min_failed << std::endl;
   ASSERT_TRUE(max_success + 1 == min_failed);
   my_lock.unlock();