From 991adad4730bf3f1a96dc5d3e25eebb14f0caf1d Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Mon, 25 Apr 2022 11:22:32 -0400 Subject: [PATCH] rgw: dbstore: add mechanism to signal gc_worker to exit This addresses a trivial hang on shutdown. Fixes: https://tracker.ceph.com/issues/55431 Signed-off-by: Matt Benjamin --- src/rgw/store/dbstore/common/dbstore.cc | 17 ++++++++++++----- src/rgw/store/dbstore/common/dbstore.h | 13 ++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/rgw/store/dbstore/common/dbstore.cc b/src/rgw/store/dbstore/common/dbstore.cc index dfb2d6490c4fb..d215df6ab9558 100644 --- a/src/rgw/store/dbstore/common/dbstore.cc +++ b/src/rgw/store/dbstore/common/dbstore.cc @@ -65,8 +65,10 @@ int DB::createGC(const DoutPrefixProvider *dpp) { } int DB::stopGC() { - if (gc_worker) + if (gc_worker) { + gc_worker->signal_stop(); gc_worker->join(); + } return 0; } @@ -2040,6 +2042,8 @@ int DB::delete_stale_objs(const DoutPrefixProvider *dpp, const std::string& buck void *DB::GC::entry() { do { + std::unique_lock lk(mtx); + ldpp_dout(dpp, 2) << " DB GC started " << dendl; int max = 100; RGWUserBuckets buckets; @@ -2071,15 +2075,18 @@ void *DB::GC::entry() { user_marker = user.id; /* XXX: If using locks, unlock here and reacquire in the next iteration */ - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + cv.wait_for(lk, std::chrono::milliseconds(100)); + if (stop_signalled) { + goto done; + } } } while(is_truncated); bucket_marker.clear(); - std::this_thread::sleep_for(std::chrono::milliseconds(gc_interval*10)); - - } while(1); + cv.wait_for(lk, std::chrono::milliseconds(gc_interval*10)); + } while(! stop_signalled); +done: return nullptr; } diff --git a/src/rgw/store/dbstore/common/dbstore.h b/src/rgw/store/dbstore/common/dbstore.h index 0779323a5daab..10056dfa452c5 100644 --- a/src/rgw/store/dbstore/common/dbstore.h +++ b/src/rgw/store/dbstore/common/dbstore.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include // this seems safe to use, at least for now--arguably, we should // prefer header-only fmt, in general #undef FMT_HEADER_ONLY @@ -1668,6 +1670,9 @@ class DB { * gc_obj_min_wait: Min. time to wait before deleting any data post its creation. * */ + std::mutex mtx; + std::condition_variable cv; + bool stop_signalled = false; uint32_t gc_interval = 24*60*60; //sec ; default: 24*60*60 uint32_t gc_obj_min_wait = 60*60; //60*60sec default std::string bucket_marker; @@ -1678,7 +1683,13 @@ class DB { dpp(_dpp), db(_db) {} void *entry() override; - + + void signal_stop() { + std::lock_guard lk_guard(mtx); + stop_signalled = true; + cv.notify_one(); + } + friend class DB; }; std::unique_ptr gc_worker; -- 2.39.5