rgw/rados: RGWReshardWait warns about blocking

Signed-off-by: Casey Bodley <cbodley@redhat.com>
This commit is contained in:
Casey Bodley 2024-06-20 16:28:02 -04:00
parent 5eda1d3353
commit fdeff76d03
4 changed files with 21 additions and 14 deletions

View File

@ -7776,7 +7776,7 @@ int RGWRados::block_while_resharding(RGWRados::BucketShard *bs,
} // if taking of lock succeeded
} // block to encapsulate recovery from incomplete reshard
ret = reshard_wait->wait(y);
ret = reshard_wait->wait(dpp, y);
if (ret < 0) {
ldpp_dout(dpp, 0) << __func__ <<
" ERROR: bucket is still resharding, please retry" << dendl;

View File

@ -7,6 +7,7 @@
#include "rgw_zone.h"
#include "driver/rados/rgw_bucket.h"
#include "rgw_asio_thread.h"
#include "rgw_reshard.h"
#include "rgw_sal.h"
#include "rgw_sal_rados.h"
@ -1261,7 +1262,7 @@ int RGWReshard::clear_bucket_resharding(const DoutPrefixProvider *dpp, const str
return 0;
}
int RGWReshardWait::wait(optional_yield y)
int RGWReshardWait::wait(const DoutPrefixProvider* dpp, optional_yield y)
{
std::unique_lock lock(mutex);
@ -1285,6 +1286,7 @@ int RGWReshardWait::wait(optional_yield y)
waiters.erase(waiters.iterator_to(waiter));
return -ec.value();
}
maybe_warn_about_blocking(dpp);
cond.wait_for(lock, duration);

View File

@ -266,7 +266,7 @@ public:
~RGWReshardWait() {
ceph_assert(going_down);
}
int wait(optional_yield y);
int wait(const DoutPrefixProvider* dpp, optional_yield y);
// unblock any threads waiting on reshard
void stop();
};

View File

@ -23,10 +23,11 @@ using Clock = RGWReshardWait::Clock;
TEST(ReshardWait, wait_block)
{
constexpr ceph::timespan wait_duration = 10ms;
const auto dpp = NoDoutPrefix{g_ceph_context, ceph_subsys_rgw};
RGWReshardWait waiter(wait_duration);
const auto start = Clock::now();
EXPECT_EQ(0, waiter.wait(null_yield));
EXPECT_EQ(0, waiter.wait(&dpp, null_yield));
const ceph::timespan elapsed = Clock::now() - start;
EXPECT_LE(wait_duration, elapsed); // waited at least 10ms
@ -37,16 +38,17 @@ TEST(ReshardWait, stop_block)
{
constexpr ceph::timespan short_duration = 10ms;
constexpr ceph::timespan long_duration = 10s;
const auto dpp = NoDoutPrefix{g_ceph_context, ceph_subsys_rgw};
RGWReshardWait long_waiter(long_duration);
RGWReshardWait short_waiter(short_duration);
const auto start = Clock::now();
std::thread thread([&long_waiter] {
EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
std::thread thread([&dpp, &long_waiter] {
EXPECT_EQ(-ECANCELED, long_waiter.wait(&dpp, null_yield));
});
EXPECT_EQ(0, short_waiter.wait(null_yield));
EXPECT_EQ(0, short_waiter.wait(&dpp, null_yield));
long_waiter.stop(); // cancel long waiter
@ -65,11 +67,12 @@ void rethrow(std::exception_ptr eptr) {
TEST(ReshardWait, wait_yield)
{
constexpr ceph::timespan wait_duration = 50ms;
const auto dpp = NoDoutPrefix{g_ceph_context, ceph_subsys_rgw};
RGWReshardWait waiter(wait_duration);
boost::asio::io_context context;
boost::asio::spawn(context, [&] (boost::asio::yield_context yield) {
EXPECT_EQ(0, waiter.wait(yield));
EXPECT_EQ(0, waiter.wait(&dpp, yield));
}, rethrow);
const auto start = Clock::now();
@ -88,6 +91,7 @@ TEST(ReshardWait, stop_yield)
{
constexpr ceph::timespan short_duration = 50ms;
constexpr ceph::timespan long_duration = 10s;
const auto dpp = NoDoutPrefix{g_ceph_context, ceph_subsys_rgw};
RGWReshardWait long_waiter(long_duration);
RGWReshardWait short_waiter(short_duration);
@ -95,14 +99,14 @@ TEST(ReshardWait, stop_yield)
boost::asio::io_context context;
boost::asio::spawn(context,
[&] (boost::asio::yield_context yield) {
EXPECT_EQ(-ECANCELED, long_waiter.wait(yield));
EXPECT_EQ(-ECANCELED, long_waiter.wait(&dpp, yield));
}, rethrow);
const auto start = Clock::now();
EXPECT_EQ(1u, context.poll()); // spawn
EXPECT_FALSE(context.stopped());
EXPECT_EQ(0, short_waiter.wait(null_yield));
EXPECT_EQ(0, short_waiter.wait(&dpp, null_yield));
long_waiter.stop(); // cancel long waiter
@ -119,6 +123,7 @@ TEST(ReshardWait, stop_multiple)
{
constexpr ceph::timespan short_duration = 50ms;
constexpr ceph::timespan long_duration = 10s;
const auto dpp = NoDoutPrefix{g_ceph_context, ceph_subsys_rgw};
RGWReshardWait long_waiter(long_duration);
RGWReshardWait short_waiter(short_duration);
@ -126,8 +131,8 @@ TEST(ReshardWait, stop_multiple)
// spawn 4 threads
std::vector<std::thread> threads;
{
auto sync_waiter([&long_waiter] {
EXPECT_EQ(-ECANCELED, long_waiter.wait(null_yield));
auto sync_waiter([&dpp, &long_waiter] {
EXPECT_EQ(-ECANCELED, long_waiter.wait(&dpp, null_yield));
});
threads.emplace_back(sync_waiter);
threads.emplace_back(sync_waiter);
@ -138,7 +143,7 @@ TEST(ReshardWait, stop_multiple)
boost::asio::io_context context;
{
auto async_waiter = [&] (boost::asio::yield_context yield) {
EXPECT_EQ(-ECANCELED, long_waiter.wait(yield));
EXPECT_EQ(-ECANCELED, long_waiter.wait(&dpp, yield));
};
boost::asio::spawn(context, async_waiter, rethrow);
boost::asio::spawn(context, async_waiter, rethrow);
@ -150,7 +155,7 @@ TEST(ReshardWait, stop_multiple)
EXPECT_EQ(4u, context.poll()); // spawn
EXPECT_FALSE(context.stopped());
EXPECT_EQ(0, short_waiter.wait(null_yield));
EXPECT_EQ(0, short_waiter.wait(&dpp, null_yield));
long_waiter.stop(); // cancel long waiter