mdlog = new MDLog(this);
balancer = new MDBalancer(this, messenger, monc);
- scrubstack = new ScrubStack(mdcache, finisher);
+ scrubstack = new ScrubStack(mdcache, clog, finisher);
inotable = new InoTable(this);
snapserver = new SnapServer(this, monc);
if (in == header->get_origin()) {
scrub_origins.erase(in);
+ clog_scrub_summary(in);
if (!header->get_recursive()) {
if (r >= 0) { // we got into the scrubbing dump it
result.dump(&(header->get_formatter()));
dout(20) << __func__ << ", from state=" << state << ", to state="
<< next_state << dendl;
state = next_state;
+ clog_scrub_summary();
}
}
*cs << ",";
}
- std::string path;
- (*inode)->make_path_string(path, true);
- *cs << (path.empty() ? "/" : path.c_str());
+ *cs << scrub_inode_path(*inode);
}
*cs << "]";
}
std::string tag(header->get_tag());
f->open_object_section(tag.c_str()); // scrub id
- std::string path;
- inode->make_path_string(path, true);
- f->dump_string("path", path.empty() ? "/" : path.c_str());
+ f->dump_string("path", scrub_inode_path(inode));
std::stringstream optss;
if (header->get_recursive()) {
CInode *in = *inode;
if (in == in->scrub_info()->header->get_origin()) {
scrub_origins.erase(in);
+ clog_scrub_summary(in);
}
MDSContext *ctx = nullptr;
return r;
}
+
+// send current scrub summary to cluster log
+void ScrubStack::clog_scrub_summary(CInode *in) {
+ if (in) {
+ std::string what;
+ if (clear_inode_stack) {
+ what = "aborted";
+ } else if (scrub_origins.count(in)) {
+ what = "queued";
+ } else {
+ what = "completed";
+ }
+ clog->info() << "scrub " << what << " for path: " << scrub_inode_path(in);
+ }
+
+ clog->info() << "scrub summary: " << scrub_summary();
+}
#include "MDSContext.h"
#include "ScrubHeader.h"
+#include "common/LogClient.h"
#include "include/elist.h"
class MDCache;
class ScrubStack {
protected:
+ // reference to global cluster log client
+ LogChannelRef &clog;
+
/// A finisher needed so that we don't re-enter kick_off_scrubs
Finisher *finisher;
public:
MDCache *mdcache;
- ScrubStack(MDCache *mdc, Finisher *finisher_) :
+ ScrubStack(MDCache *mdc, LogChannelRef &clog, Finisher *finisher_) :
+ clog(clog),
finisher(finisher_),
inode_stack(member_offset(CInode, item_scrub)),
scrubs_in_progress(0),
MDSContext *on_finish) {
enqueue_inode(in, header, on_finish, true);
scrub_origins.emplace(in);
+ clog_scrub_summary(in);
}
/** Like enqueue_inode_top, but we wait for all pending scrubs before
* starting this one.
MDSContext *on_finish) {
enqueue_inode(in, header, on_finish, false);
scrub_origins.emplace(in);
+ clog_scrub_summary(in);
}
/**
* Completion context is complete with -ECANCELED.
*/
void abort_pending_scrubs();
+
+ /**
+ * Return path for a given inode.
+ * @param in inode to make path entry.
+ */
+ std::string scrub_inode_path(CInode *in) {
+ std::string path;
+ in->make_path_string(path, true);
+ return (path.empty() ? "/" : path.c_str());
+ }
+
+ /**
+ * Send scrub information (queued/finished scrub path and summary)
+ * to cluster log.
+ * @param in inode for which scrub has been queued or finished.
+ */
+ void clog_scrub_summary(CInode *in=nullptr);
};
#endif /* SCRUBSTACK_H_ */