From: John Spray Date: Thu, 13 Feb 2014 12:59:00 +0000 (+0000) Subject: mds: Add dump-journal-entries X-Git-Tag: v0.79~189^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1263%2Fhead;p=ceph.git mds: Add dump-journal-entries This adds a somewhat-human-readable peer to the 'dump-journal' command. Signed-off-by: John Spray --- diff --git a/src/ceph_mds.cc b/src/ceph_mds.cc index 14b84097bc27..1f1fbd319d7d 100644 --- a/src/ceph_mds.cc +++ b/src/ceph_mds.cc @@ -56,7 +56,9 @@ void usage() << " --debug_mds n\n" << " debug MDS level (e.g. 10)\n" << " --dump-journal rank filename\n" - << " dump the MDS journal for rank.\n" + << " dump the MDS journal (binary) for rank.\n" + << " --dump-journal-entries rank filename\n" + << " dump the MDS journal (JSON) for rank.\n" << " --journal-check rank\n" << " replay the journal for rank, then exit\n" << " --hot-standby rank\n" @@ -79,6 +81,11 @@ static int do_cmds_special_action(const std::string &action, journal_dumper.init(rank); journal_dumper.dump(dump_file.c_str()); journal_dumper.shutdown(); + } else if (action == "dump-journal-entries") { + Dumper journal_dumper; + journal_dumper.init(rank); + journal_dumper.dump_entries(); + journal_dumper.shutdown(); } else if (action == "undump-journal") { dout(0) << "undumping journal for mds." << rank << " from " << dump_file << dendl; Dumper journal_dumper; @@ -171,6 +178,10 @@ int main(int argc, const char **argv) } dump_file = *i++; } + else if (ceph_argparse_witharg(args, i, &val, "--dump-journal-entries", (char*)NULL)){ + set_special_action(action, "dump-journal-entries"); + rank = parse_rank("dump-journal-entries", val); + } else if (ceph_argparse_witharg(args, i, &val, "--reset-journal", (char*)NULL)) { set_special_action(action, "reset-journal"); rank = parse_rank("reset-journal", val); diff --git a/src/mds/Dumper.cc b/src/mds/Dumper.cc index fd6aef9579aa..f7f18c9bf3d9 100644 --- a/src/mds/Dumper.cc +++ b/src/mds/Dumper.cc @@ -22,6 +22,7 @@ #include "common/safe_io.h" #include "mds/Dumper.h" #include "mds/mdstypes.h" +#include "mds/LogEvent.h" #include "osdc/Journaler.h" #define dout_subsys ceph_subsys_mds @@ -43,13 +44,12 @@ int Dumper::init(int rank_) } -void Dumper::dump(const char *dump_file) +int Dumper::recover_journal() { bool done = false; - int r = 0; - Cond cond; - Mutex localLock("dump:lock"); + Mutex localLock("dump:recover_journal"); + int r; lock.Lock(); journaler->recover(new C_SafeCond(&localLock, &cond, &done, &r)); @@ -61,10 +61,25 @@ void Dumper::dump(const char *dump_file) if (r < 0) { // Error derr << "error on recovery: " << cpp_strerror(r) << dendl; + return r; } else { dout(10) << "completed journal recovery" << dendl; + return 0; } +} + + +void Dumper::dump(const char *dump_file) +{ + bool done = false; + int r = 0; + Cond cond; + Mutex localLock("dump:lock"); + r = recover_journal(); + if (r) { + return; + } uint64_t start = journaler->get_read_pos(); uint64_t end = journaler->get_write_pos(); uint64_t len = end-start; @@ -197,3 +212,63 @@ void Dumper::undump(const char *dump_file) VOID_TEMP_FAILURE_RETRY(::close(fd)); cout << "done." << std::endl; } + + +/** + * Write JSON-formatted log entries to standard out. + */ +void Dumper::dump_entries() +{ + Mutex localLock("dump_entries"); + JSONFormatter jf(true); + + int r = recover_journal(); + if (r) { + return; + } + + jf.open_array_section("log"); + bool got_data = true; + lock.Lock(); + // Until the journal is empty, pop an event or wait for one to + // be available. + dout(10) << "Journaler read/write/size: " + << journaler->get_read_pos() << "/" << journaler->get_write_pos() + << "/" << journaler->get_write_pos() - journaler->get_read_pos() << dendl; + while (journaler->get_read_pos() != journaler->get_write_pos()) { + bufferlist entry_bl; + got_data = journaler->try_read_entry(entry_bl); + dout(10) << "try_read_entry: " << got_data << dendl; + if (got_data) { + LogEvent *le = LogEvent::decode(entry_bl); + if (!le) { + dout(0) << "Error decoding LogEvent" << dendl; + break; + } else { + jf.open_object_section("log_event"); + jf.dump_unsigned("type", le->get_type()); + jf.dump_unsigned("start_off", le->get_start_off()); + jf.dump_unsigned("stamp_sec", le->get_stamp().tv.tv_sec); + jf.dump_unsigned("stamp_nsec", le->get_stamp().tv.tv_nsec); + le->dump(&jf); + jf.close_section(); + delete le; + } + } else { + bool done = false; + Cond cond; + + journaler->wait_for_readable(new C_SafeCond(&localLock, &cond, &done)); + lock.Unlock(); + localLock.Lock(); + while (!done) + cond.Wait(localLock); + localLock.Unlock(); + lock.Lock(); + } + } + lock.Unlock(); + jf.close_section(); + jf.flush(cout); + return; +} diff --git a/src/mds/Dumper.h b/src/mds/Dumper.h index 13e3adddd8e9..6218ef427785 100644 --- a/src/mds/Dumper.h +++ b/src/mds/Dumper.h @@ -38,8 +38,10 @@ public: void handle_mds_map(MMDSMap* m); int init(int rank); + int recover_journal(); void dump(const char *dumpfile); void undump(const char *dumpfile); + void dump_entries(); }; #endif /* JOURNAL_DUMPER_H_ */