From db4b62b4622b44f4bedc757bdf401dff6aa0f880 Mon Sep 17 00:00:00 2001 From: Nitzan Mordechai Date: Wed, 7 May 2025 13:37:34 +0000 Subject: [PATCH] test/librados/aio_cxx: skip EIO boundary assertion when no in-flight I/Os MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 07319d9a37ef70b6422e26eba8a251f711db2c6b) --- src/test/librados/aio_cxx.cc | 41 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/test/librados/aio_cxx.cc b/src/test/librados/aio_cxx.cc index 5e35869b5c2f3..b0b7b6c4e7d50 100644 --- a/src/test/librados/aio_cxx.cc +++ b/src/test/librados/aio_cxx.cc @@ -1,6 +1,8 @@ +#include #include #include #include +#include #include #include #include @@ -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 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(); -- 2.39.5