From 15d8f7b419c349e0b1ccd0f35b631fc159f75fdd Mon Sep 17 00:00:00 2001 From: Venky Shankar Date: Mon, 5 Nov 2018 00:54:24 -0500 Subject: [PATCH] mds: introduce "scrub start" tell interface to initiate scrub This should be preferred over the traditional asok interface which would probably get deprecated (soon). Signed-off-by: Venky Shankar --- src/mds/MDCache.cc | 1 + src/mds/MDSDaemon.cc | 2 ++ src/mds/MDSRank.cc | 56 ++++++++++++++++++++++++++++++++++---------- src/mds/MDSRank.h | 5 +++- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index eb9aacfa3f3..cd1361540ec 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -12339,6 +12339,7 @@ public: formatter->open_object_section("results"); formatter->dump_int("return_code", r); formatter->close_section(); // results + r = 0; // already dumped in formatter } if (on_finish) on_finish->complete(r); diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 6fbe913043e..c6cd4239a8b 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -682,6 +682,8 @@ const std::vector& MDSDaemon::get_commands() "name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", "show heap usage info (available only if compiled with tcmalloc)"), MDSCommand("cache drop name=timeout,type=CephInt,range=0,req=false", "trim cache and optionally request client to release all caps and flush the journal"), + MDSCommand("scrub start name=path,type=CephString name=scrubops,type=CephChoices,strings=force|recursive|repair,n=N,req=false name=tag,type=CephString,req=false", + "scrub an inode and output results"), }; return commands; }; diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index f9230cafa11..9b3a8643746 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2453,7 +2453,10 @@ bool MDSRankDispatcher::handle_asok_command(std::string_view command, vector scrubop_vec; cmd_getval(g_ceph_context, cmdmap, "scrubops", scrubop_vec); cmd_getval(g_ceph_context, cmdmap, "path", path); - command_scrub_path(f, path, scrubop_vec); + + C_SaferCond cond; + command_scrub_start(f, path, "", scrubop_vec, &cond); + cond.wait(); } else if (command == "tag path") { string path; cmd_getval(g_ceph_context, cmdmap, "path", path); @@ -2617,6 +2620,24 @@ private: uint64_t timeout; }; +class C_ScrubExecAndReply : public C_ExecAndReply { +public: + C_ScrubExecAndReply(MDSRank *mds, const MCommand::const_ref &m, + const std::string &path, const std::string &tag, + const std::vector &scrubop) + : C_ExecAndReply(mds, m), path(path), tag(tag), scrubop(scrubop) { + } + + void exec() override { + mds->command_scrub_start(&f, path, tag, scrubop, this); + } + +private: + std::string path; + std::string tag; + std::vector scrubop; +}; + /** * This function drops the mds_lock, so don't do anything with * MDSRank after calling it (we could have gone into shutdown): just @@ -2702,25 +2723,24 @@ void MDSRankDispatcher::dump_sessions(const SessionFilter &filter, Formatter *f) f->close_section(); //sessions } -void MDSRank::command_scrub_path(Formatter *f, std::string_view path, vector& scrubop_vec) +void MDSRank::command_scrub_start(Formatter *f, + std::string_view path, std::string_view tag, + const vector& scrubop_vec, Context *on_finish) { bool force = false; bool recursive = false; bool repair = false; - for (vector::iterator i = scrubop_vec.begin() ; i != scrubop_vec.end(); ++i) { - if (*i == "force") + for (auto &op : scrubop_vec) { + if (op == "force") force = true; - else if (*i == "recursive") + else if (op == "recursive") recursive = true; - else if (*i == "repair") + else if (op == "repair") repair = true; } - C_SaferCond scond; - { - std::lock_guard l(mds_lock); - mdcache->enqueue_scrub(path, "", force, recursive, repair, f, &scond); - } - scond.wait(); + + std::lock_guard l(mds_lock); + mdcache->enqueue_scrub(path, tag, force, recursive, repair, f, on_finish); // scrub_dentry() finishers will dump the data for us; we're done! } @@ -3430,6 +3450,18 @@ bool MDSRankDispatcher::handle_command( *run_later = create_async_exec_context(new C_CacheDropExecAndReply (this, m, (uint64_t)timeout)); return true; + } else if (prefix == "scrub start") { + string path; + string tag; + vector scrubop_vec; + cmd_getval(g_ceph_context, cmdmap, "scrubops", scrubop_vec); + cmd_getval(g_ceph_context, cmdmap, "path", path); + cmd_getval(g_ceph_context, cmdmap, "tag", tag); + + *need_reply = false; + *run_later = create_async_exec_context(new C_ScrubExecAndReply + (this, m, path, tag, scrubop_vec)); + return true; } else { return false; } diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 2ca8c50bcfb..38984d640f6 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -140,6 +140,7 @@ class MDSRank { friend class C_Drop_Cache; friend class C_CacheDropExecAndReply; + friend class C_ScrubExecAndReply; mds_rank_t get_nodeid() const { return whoami; } int64_t get_metadata_pool(); @@ -459,7 +460,9 @@ class MDSRank { protected: void dump_clientreplay_status(Formatter *f) const; - void command_scrub_path(Formatter *f, std::string_view path, vector& scrubop_vec); + void command_scrub_start(Formatter *f, + std::string_view path, std::string_view tag, + const vector& scrubop_vec, Context *on_finish); void command_tag_path(Formatter *f, std::string_view path, std::string_view tag); void command_flush_path(Formatter *f, std::string_view path); -- 2.39.5