From 466d3cac3aac14c486e429b72ac47a8636d744be Mon Sep 17 00:00:00 2001 From: Leonid Usov Date: Mon, 6 May 2024 19:57:53 +0300 Subject: [PATCH] squid: mds: don't stall the asok thread for flush commands Signed-off-by: Leonid Usov Fixes: https://tracker.ceph.com/issues/65803 (cherry picked from commit a4dc88140071f9cdfe5654402067434728fee469) Fixes: https://tracker.ceph.com/issues/66103 --- src/mds/MDSRank.cc | 111 +++++++++++++++++---------------------------- src/mds/MDSRank.h | 4 -- 2 files changed, 42 insertions(+), 73 deletions(-) diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 4bdf169385eff..94a48ae913bed 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2657,6 +2657,28 @@ void MDSRankDispatcher::handle_asok_command( CachedStackStringStream css; bufferlist outbl; dout(10) << __func__ << ": " << command << dendl; + + struct AsyncResponse : Context { + Formatter* f; + decltype(on_finish) do_respond; + std::basic_ostringstream css; + + AsyncResponse(Formatter* f, decltype(on_finish)&& respond_action) + : f(f), do_respond(std::forward(respond_action)) {} + + void finish(int rc) override { + f->open_object_section("result"); + if (!css.view().empty()) { + f->dump_string("message", css.view()); + } + f->dump_int("return_code", rc); + f->close_section(); + + bufferlist outbl; + do_respond(rc, {}, outbl); + } + }; + if (command == "dump_ops_in_flight") { if (!op_tracker.dump_ops_in_flight(f)) { *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable"; @@ -2889,20 +2911,13 @@ void MDSRankDispatcher::handle_asok_command( goto out; } + auto respond = new AsyncResponse(f, std::move(on_finish)); finisher->queue( new LambdaContext( - [this, on_finish, f](int r) { - command_scrub_abort( - f, - new LambdaContext( - [on_finish, f](int r) { - bufferlist outbl; - f->open_object_section("result"); - f->dump_int("return_code", r); - f->close_section(); - on_finish(r, {}, outbl); - })); - })); + [this, respond](int r) { + std::lock_guard l(mds_lock); + scrubstack->scrub_abort(respond); + })); return; } else if (command == "scrub pause") { if (whoami != 0) { @@ -2911,20 +2926,13 @@ void MDSRankDispatcher::handle_asok_command( goto out; } + auto respond = new AsyncResponse(f, std::move(on_finish)); finisher->queue( new LambdaContext( - [this, on_finish, f](int r) { - command_scrub_pause( - f, - new LambdaContext( - [on_finish, f](int r) { - bufferlist outbl; - f->open_object_section("result"); - f->dump_int("return_code", r); - f->close_section(); - on_finish(r, {}, outbl); - })); - })); + [this, respond](int r) { + std::lock_guard l(mds_lock); + scrubstack->scrub_pause(respond); + })); return; } else if (command == "scrub resume") { if (whoami != 0) { @@ -2949,9 +2957,17 @@ void MDSRankDispatcher::handle_asok_command( } else if (command == "flush_path") { string path; cmd_getval(cmdmap, "path", path); - command_flush_path(f, path); + + std::lock_guard l(mds_lock); + mdcache->flush_dentry(path, new AsyncResponse(f, std::move(on_finish))); + return; } else if (command == "flush journal") { - command_flush_journal(f); + auto respond = new AsyncResponse(f, std::move(on_finish)); + C_Flush_Journal* flush_journal = new C_Flush_Journal(mdcache, mdlog, this, &respond->css, respond); + + std::lock_guard locker(mds_lock); + flush_journal->send(); + return; } else if (command == "get subtrees") { command_get_subtrees(f); } else if (command == "export dir") { @@ -3171,16 +3187,6 @@ void MDSRank::command_tag_path(Formatter *f, scond.wait(); } -void MDSRank::command_scrub_abort(Formatter *f, Context *on_finish) { - std::lock_guard l(mds_lock); - scrubstack->scrub_abort(on_finish); -} - -void MDSRank::command_scrub_pause(Formatter *f, Context *on_finish) { - std::lock_guard l(mds_lock); - scrubstack->scrub_pause(on_finish); -} - void MDSRank::command_scrub_resume(Formatter *f) { std::lock_guard l(mds_lock); int r = scrubstack->scrub_resume(); @@ -3195,39 +3201,6 @@ void MDSRank::command_scrub_status(Formatter *f) { scrubstack->scrub_status(f); } -void MDSRank::command_flush_path(Formatter *f, std::string_view path) -{ - C_SaferCond scond; - { - std::lock_guard l(mds_lock); - mdcache->flush_dentry(path, &scond); - } - int r = scond.wait(); - f->open_object_section("results"); - f->dump_int("return_code", r); - f->close_section(); // results -} - -// synchronous wrapper around "journal flush" asynchronous context -// execution. -void MDSRank::command_flush_journal(Formatter *f) { - ceph_assert(f != NULL); - - C_SaferCond cond; - CachedStackStringStream css; - { - std::lock_guard locker(mds_lock); - C_Flush_Journal *flush_journal = new C_Flush_Journal(mdcache, mdlog, this, css.get(), &cond); - flush_journal->send(); - } - int r = cond.wait(); - - f->open_object_section("result"); - f->dump_string("message", css->strv()); - f->dump_int("return_code", r); - f->close_section(); -} - void MDSRank::command_get_subtrees(Formatter *f) { ceph_assert(f != NULL); diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index de9f140d3f4d4..02b9466f43942 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -504,13 +504,9 @@ class MDSRank { void command_tag_path(Formatter *f, std::string_view path, std::string_view tag); // scrub control commands - void command_scrub_abort(Formatter *f, Context *on_finish); - void command_scrub_pause(Formatter *f, Context *on_finish); void command_scrub_resume(Formatter *f); void command_scrub_status(Formatter *f); - void command_flush_path(Formatter *f, std::string_view path); - void command_flush_journal(Formatter *f); void command_get_subtrees(Formatter *f); void command_export_dir(Formatter *f, std::string_view path, mds_rank_t dest); -- 2.39.5