"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;
};
vector<string> 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);
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<std::string> &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<std::string> scrubop;
+};
+
/**
* This function drops the mds_lock, so don't do anything with
* MDSRank after calling it (we could have gone into shutdown): just
f->close_section(); //sessions
}
-void MDSRank::command_scrub_path(Formatter *f, std::string_view path, vector<string>& scrubop_vec)
+void MDSRank::command_scrub_start(Formatter *f,
+ std::string_view path, std::string_view tag,
+ const vector<string>& scrubop_vec, Context *on_finish)
{
bool force = false;
bool recursive = false;
bool repair = false;
- for (vector<string>::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!
}
*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<string> 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;
}
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();
protected:
void dump_clientreplay_status(Formatter *f) const;
- void command_scrub_path(Formatter *f, std::string_view path, vector<string>& scrubop_vec);
+ void command_scrub_start(Formatter *f,
+ std::string_view path, std::string_view tag,
+ const vector<string>& 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);