]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: don't stall the asok thread for flush commands
authorLeonid Usov <leonid.usov@ibm.com>
Mon, 6 May 2024 16:57:53 +0000 (19:57 +0300)
committerLeonid Usov <leonid.usov@ibm.com>
Mon, 20 May 2024 08:53:08 +0000 (11:53 +0300)
Signed-off-by: Leonid Usov <leonid.usov@ibm.com>
Fixes: https://tracker.ceph.com/issues/65803
(cherry picked from commit a4dc88140071f9cdfe5654402067434728fee469)
Fixes: https://tracker.ceph.com/issues/66047
src/mds/MDSRank.cc
src/mds/MDSRank.h

index aa6a8c162f4f5cbf1cb06a4b17f78022c5a6347f..fa2a1bbb0c4a7f6b3358589aef13fd31d7cbd171 100644 (file)
@@ -2623,6 +2623,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<char> css;
+
+    AsyncResponse(Formatter* f, decltype(on_finish)&& respond_action)
+      : f(f), do_respond(std::forward<decltype(on_finish)>(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";
@@ -2767,20 +2789,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) {
@@ -2789,20 +2804,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) {
@@ -2827,9 +2835,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") {
@@ -3042,16 +3058,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();
@@ -3066,39 +3072,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);
index a9e8da1817a26368aa6a4b9db2d9abd64115d5bb..54f56bfcd3c965e25939c70a4bdae012e417bc5a 100644 (file)
@@ -499,13 +499,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);