]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Add dump-journal-entries 1263/head
authorJohn Spray <john.spray@inktank.com>
Thu, 13 Feb 2014 12:59:00 +0000 (12:59 +0000)
committerJohn Spray <john.spray@inktank.com>
Wed, 26 Feb 2014 18:19:06 +0000 (18:19 +0000)
This adds a somewhat-human-readable peer to
the 'dump-journal' command.

Signed-off-by: John Spray <john.spray@inktank.com>
src/ceph_mds.cc
src/mds/Dumper.cc
src/mds/Dumper.h

index 14b84097bc27458ddaf5edf2b9117a2272966c05..1f1fbd319d7d7fed45056c3768c2e4eb31c3d30f 100644 (file)
@@ -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);
index fd6aef9579aac47ebf0f7da9ac87496e59671b36..f7f18c9bf3d9574a49edc02a754a55b09326cce0 100644 (file)
@@ -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;
+}
index 13e3adddd8e9ff7eb4c68540ac39dfa3576056e4..6218ef427785f027a20ee49ede336ed361d7743e 100644 (file)
@@ -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_ */