]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-monstore-tool: add MonitorDBStore trace dumper
authorSamuel Just <sam.just@inktank.com>
Thu, 2 May 2013 22:19:06 +0000 (15:19 -0700)
committerSage Weil <sage@inktank.com>
Wed, 8 May 2013 18:03:43 +0000 (11:03 -0700)
Signed-off-by: Samuel Just <sam.just@inktank.com>
src/mon/MonitorDBStore.h
src/tools/ceph-monstore-tool.cc

index 3b53a8be80d08c937903fb553f97b875a92cd07e..b0f9eb0d74adf04dae22d261c16e5b831695f76d 100644 (file)
@@ -136,13 +136,13 @@ class MonitorDBStore
       return ops.size();
     }
 
-    void dump(ceph::Formatter *f) {
+    void dump(ceph::Formatter *f, bool dump_val=false) const {
       f->open_object_section("transaction");
       f->open_array_section("ops");
-      list<Op>::iterator it;
+      list<Op>::const_iterator it;
       int op_num = 0;
       for (it = ops.begin(); it != ops.end(); ++it) {
-       Op& op = *it;
+       const Op& op = *it;
        f->open_object_section("op");
        f->dump_int("op_num", op_num++);
        switch (op.type) {
@@ -151,10 +151,12 @@ class MonitorDBStore
            f->dump_string("type", "PUT");
            f->dump_string("prefix", op.prefix);
            f->dump_string("key", op.key);
-           ostringstream os;
-           op.bl.hexdump(os);
            f->dump_unsigned("length", op.bl.length());
-           f->dump_string("bl", os.str());
+           if (dump_val) {
+             ostringstream os;
+             op.bl.hexdump(os);
+             f->dump_string("bl", os.str());
+           }
          }
          break;
        case OP_ERASE:
@@ -184,7 +186,7 @@ class MonitorDBStore
     }
   };
 
-  int apply_transaction(MonitorDBStore::Transaction& t) {
+  int apply_transaction(const MonitorDBStore::Transaction& t) {
     KeyValueDB::Transaction dbt = db->get_transaction();
 
     if (do_dump) {
@@ -194,8 +196,8 @@ class MonitorDBStore
     }
 
     list<string> compact_prefixes;
-    for (list<Op>::iterator it = t.ops.begin(); it != t.ops.end(); ++it) {
-      Op& op = *it;
+    for (list<Op>::const_iterator it = t.ops.begin(); it != t.ops.end(); ++it) {
+      const Op& op = *it;
       switch (op.type) {
       case Transaction::OP_PUT:
        dbt->set(op.prefix, op.key, op.bl);
index 9b6a22afd02a59878689d69a0116b2c893d654bf..37a49fb6f9458c3de010bf17763e1a68c7f63ba6 100644 (file)
 #include "global/global_init.h"
 #include "os/LevelDBStore.h"
 #include "mon/MonitorDBStore.h"
+#include "common/Formatter.h"
 
 namespace po = boost::program_options;
 using namespace std;
 
+class TraceIter {
+  int fd;
+  unsigned idx;
+  MonitorDBStore::Transaction t;
+public:
+  TraceIter(string fname) : fd(-1), idx(-1) {
+    fd = ::open(fname.c_str(), O_RDONLY);
+  }
+  bool valid() {
+    return fd != -1;
+  }
+  const MonitorDBStore::Transaction &cur() {
+    assert(valid());
+    return t;
+  }
+  unsigned num() { return idx; }
+  void next() {
+    ++idx;
+    bufferlist bl;
+    int r = bl.read_fd(fd, 6);
+    if (r < 0) {
+      std::cerr << "Got error: " << cpp_strerror(r) << " on read_fd"
+               << std::endl;
+      ::close(fd);
+      fd = -1;
+      return;
+    } else if ((unsigned)r < 6) {
+      std::cerr << "short read" << std::endl;
+      ::close(fd);
+      fd = -1;
+      return;
+    }
+    bufferlist::iterator bliter = bl.begin();
+    uint8_t ver, ver2;
+    ::decode(ver, bliter);
+    ::decode(ver2, bliter);
+    uint32_t len;
+    ::decode(len, bliter);
+    r = bl.read_fd(fd, len);
+    if (r < 0) {
+      std::cerr << "Got error: " << cpp_strerror(r) << " on read_fd"
+               << std::endl;
+      ::close(fd);
+      fd = -1;
+      return;
+    } else if ((unsigned)r < len) {
+      std::cerr << "short read" << std::endl;
+      ::close(fd);
+      fd = -1;
+      return;
+    }
+    bliter = bl.begin();
+    t.decode(bliter);
+  }
+  void init() {
+    next();
+  }
+  ~TraceIter() {
+    if (fd != -1) {
+      ::close(fd);
+      fd = -1;
+    }
+  }
+};
+
 int main(int argc, char **argv) {
   po::options_description desc("Allowed options");
   int version = -1;
-  string store_path, cmd, out_path;
+  string store_path, cmd, out_path, tfile;
+  unsigned dstart = 0;
+  unsigned dstop = ~0;
   desc.add_options()
     ("help", "produce help message")
     ("mon-store-path", po::value<string>(&store_path),
@@ -47,6 +115,12 @@ int main(int argc, char **argv) {
      "out path")
     ("version", po::value<int>(&version),
      "version requested")
+    ("trace-file", po::value<string>(&tfile),
+     "trace file")
+    ("dump-start", po::value<unsigned>(&dstart),
+     "transaction num to start dumping at")
+    ("dump-end", po::value<unsigned>(&dstop),
+     "transaction num to stop dumping at")
     ("command", po::value<string>(&cmd),
      "command")
     ;
@@ -97,13 +171,20 @@ int main(int argc, char **argv) {
   }
 
   MonitorDBStore st(store_path);
-  stringstream ss;
-  int r = st.open(ss);
-  if (r < 0) {
-    std::cerr << ss.str() << std::endl;
-    goto done;
+  if (store_path.size()) {
+    stringstream ss;
+    int r = st.open(ss);
+    if (r < 0) {
+      std::cerr << ss.str() << std::endl;
+      goto done;
+    }
   }
   if (cmd == "getosdmap") {
+    if (!store_path.size()) {
+      std::cerr << "need mon store path" << std::endl;
+      std::cerr << desc << std::endl;
+      goto done;
+    }
     version_t v;
     if (version == -1) {
       v = st.get("osdmap", "last_committed");
@@ -119,6 +200,29 @@ int main(int argc, char **argv) {
       goto done;
     }
     bl.write_fd(fd);
+  } else if (cmd == "dump-trace") {
+    if (tfile.empty()) {
+      std::cerr << "Need trace_file" << std::endl;
+      std::cerr << desc << std::endl;
+      goto done;
+    }
+    TraceIter iter(tfile.c_str());
+    iter.init();
+    while (true) {
+      if (!iter.valid())
+       break;
+      if (iter.num() >= dstop) {
+       break;
+      }
+      if (iter.num() >= dstart) {
+       JSONFormatter f(true);
+       iter.cur().dump(&f, false);
+       f.flush(std::cout);
+       std::cout << std::endl;
+      }
+      iter.next();
+    }
+    std::cerr << "Read up to transaction " << iter.num() << std::endl;
   } else {
     std::cerr << "Unrecognized command: " << cmd << std::endl;
     goto done;