]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds,mon: add 'mds metadata' command
authorKefu Chai <kchai@redhat.com>
Tue, 31 Mar 2015 08:36:52 +0000 (16:36 +0800)
committerKefu Chai <kchai@redhat.com>
Thu, 7 May 2015 14:29:39 +0000 (07:29 -0700)
Related: #10904
Signed-off-by: Kefu Chai <kchai@redhat.com>
qa/workunits/cephtool/test.sh
src/mds/Beacon.cc
src/messages/MMDSBeacon.h
src/messages/MMonMetadata.h
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h
src/mon/MonCommands.h

index 03785ce4d3cb603803fad1b56b669f7730291ffa..b4b41f83a9066c0365f3b39c9b33643ab4ad3ae5 100755 (executable)
@@ -692,6 +692,9 @@ function test_mon_mds()
   ceph mds compat show
   expect_false ceph mds deactivate 2
   ceph mds dump
+  for mds_gid in $(get_mds_gids) ; do
+      ceph mds metadata $mds_id
+  done
   # XXX mds fail, but how do you undo it?
   mdsmapfile=$TMPDIR/mdsmap.$$
   current_epoch=$(ceph mds getmap -o $mdsmapfile --no-log-to-stderr 2>&1 | grep epoch | sed 's/.*epoch //')
index 35265db52303f3c3729aada0d554f1678266e639..cc7fa2bdce1c0e52da52d23110344cb6627e1f28 100644 (file)
@@ -16,6 +16,7 @@
 #include "common/dout.h"
 #include "common/HeartbeatMap.h"
 #include "include/stringify.h"
+#include "include/util.h"
 
 #include "messages/MMDSBeacon.h"
 #include "mon/MonClient.h"
@@ -206,7 +207,12 @@ void Beacon::_send()
   beacon->set_standby_for_name(standby_for_name);
   beacon->set_health(health);
   beacon->set_compat(compat);
-
+  // piggyback the sys info on beacon msg
+  if (want_state == MDSMap::STATE_BOOT) {
+    map<string, string> sys_info;
+    collect_sys_info(&sys_info, cct);
+    beacon->set_sys_info(sys_info);
+  }
   monc->send_mon_message(beacon);
 }
 
index ab53760ace4ecd879bed0cec47a98acb2f53a6ba..da551f4e0401086d9e5e538f22b054b2de3fe957 100644 (file)
@@ -122,7 +122,7 @@ WRITE_CLASS_ENCODER(MDSHealth)
 
 class MMDSBeacon : public PaxosServiceMessage {
 
-  static const int HEAD_VERSION = 3;
+  static const int HEAD_VERSION = 4;
   static const int COMPAT_VERSION = 2;
 
   uuid_d fsid;
@@ -138,6 +138,8 @@ class MMDSBeacon : public PaxosServiceMessage {
 
   MDSHealth health;
 
+  map<string, string> sys_info;
+
  public:
   MMDSBeacon() : PaxosServiceMessage(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION) { }
   MMDSBeacon(const uuid_d &f, mds_gid_t g, string& n, epoch_t les, MDSMap::DaemonState st, version_t se) : 
@@ -169,6 +171,9 @@ public:
   void set_standby_for_name(string& n) { standby_for_name = n; }
   void set_standby_for_name(const char* c) { standby_for_name.assign(c); }
 
+  const map<string, string>& get_sys_info() const { return sys_info; }
+  void set_sys_info(const map<string, string>& i) { sys_info = i; }
+
   void print(ostream& out) const {
     out << "mdsbeacon(" << global_id << "/" << name << " " << ceph_mds_state_name(state) 
        << " seq " << seq << " v" << version << ")";
@@ -185,6 +190,9 @@ public:
     ::encode(standby_for_name, payload);
     ::encode(compat, payload);
     ::encode(health, payload);
+    if (state == MDSMap::STATE_BOOT) {
+      ::encode(sys_info, payload);
+    }
   }
   void decode_payload() {
     bufferlist::iterator p = payload.begin();
@@ -201,6 +209,10 @@ public:
     if (header.version >= 3) {
       ::decode(health, p);
     }
+    if (state == MDSMap::STATE_BOOT &&
+       header.version >= 4) {
+      ::decode(sys_info, p);
+    }
   }
 };
 
index 6c1896628f834ab941cec06ee531feb8c626520e..ae56611517cf902a9ffdf9bc62c654f0dd00dc05 100644 (file)
@@ -28,7 +28,7 @@ private:
 
 public:
   MMonMetadata() :
-    Message(CEPH_MSG_MON_METADATA, HEAD_VERSION)
+    Message(CEPH_MSG_MON_METADATA)
   {}
   MMonMetadata(const Metadata& metadata) :
     Message(CEPH_MSG_MON_METADATA, HEAD_VERSION),
index f5d2b3d7eb04de31623ddc655bae751d80e720c0..c79094a45f03ca9f695ba930ad4c1ef00420c2f4 100644 (file)
@@ -70,7 +70,7 @@ template<> bool cmd_getval(CephContext *cct, const cmdmap_t& cmdmap,
   return cmd_getval(cct, cmdmap, k, (int64_t&)val);
 }
 
-
+static const string MDS_METADATA_PREFIX("mds_metadata");
 
 
 // my methods
@@ -170,10 +170,12 @@ void MDSMonitor::encode_pending(MonitorDBStore::TransactionRef t)
     i->second.encode(bl);
     t->put(MDS_HEALTH_PREFIX, stringify(i->first), bl);
   }
+
   for (std::set<uint64_t>::iterator i = pending_daemon_health_rm.begin();
       i != pending_daemon_health_rm.end(); ++i) {
     t->erase(MDS_HEALTH_PREFIX, stringify(*i));
   }
+  remove_from_metadata(t);
   pending_daemon_health_rm.clear();
 }
 
@@ -489,6 +491,7 @@ bool MDSMonitor::prepare_beacon(MMDSBeacon *m)
       pending_mdsmap.compat = m->get_compat();
     }
 
+    update_metadata(m->get_global_id(), m->get_sys_info());
   } else {
     // state change
     MDSMap::mds_info_t& info = pending_mdsmap.get_info_gid(gid);
@@ -767,6 +770,15 @@ bool MDSMonitor::preprocess_command(MMonCommand *m)
       if (p != &mdsmap)
        delete p;
     }
+  } else if (prefix == "mds metadata") {
+    string who;
+    cmd_getval(g_ceph_context, cmdmap, "who", who);
+    if (!f)
+      f.reset(Formatter::create("json-pretty"));
+    f->open_object_section("mds_metadata");
+    r = dump_metadata(who, f.get(), ss);
+    f->close_section();
+    f->flush(ds);
   } else if (prefix == "mds getmap") {
     epoch_t e;
     int64_t epocharg;
@@ -1698,6 +1710,88 @@ void MDSMonitor::check_sub(Subscription *sub)
   }
 }
 
+void MDSMonitor::update_metadata(mds_gid_t gid,
+                                const map<string, string>& metadata)
+{
+  if (metadata.empty()) {
+    return;
+  }
+  bufferlist bl;
+  int err = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl);
+  map<mds_gid_t, Metadata> last_metadata;
+  if (!err) {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(last_metadata, iter);
+    bl.clear();
+  }
+  last_metadata[gid] = metadata;
+
+  MonitorDBStore::TransactionRef t = paxos->get_pending_transaction();
+  ::encode(last_metadata, bl);
+  t->put(MDS_METADATA_PREFIX, "last_metadata", bl);
+  paxos->trigger_propose();
+}
+
+void MDSMonitor::remove_from_metadata(MonitorDBStore::TransactionRef t)
+{
+  bufferlist bl;
+  int err = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl);
+  map<mds_gid_t, Metadata> last_metadata;
+  if (err) {
+    return;
+  }
+  bufferlist::iterator iter = bl.begin();
+  ::decode(last_metadata, iter);
+  bl.clear();
+
+  if (pending_daemon_health_rm.empty()) {
+    return;
+  }
+  for (std::set<uint64_t>::const_iterator to_remove = pending_daemon_health_rm.begin();
+       to_remove != pending_daemon_health_rm.end(); ++to_remove) {
+    last_metadata.erase(mds_gid_t(*to_remove));
+  }
+  ::encode(last_metadata, bl);
+  t->put(MDS_METADATA_PREFIX, "last_metadata", bl);
+}
+
+int MDSMonitor::load_metadata(map<mds_gid_t, Metadata>& m)
+{
+  bufferlist bl;
+  int r = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl);
+  if (r)
+    return r;
+
+  bufferlist::iterator it = bl.begin();
+  ::decode(m, it);
+  return 0;
+}
+
+int MDSMonitor::dump_metadata(const std::string &who, Formatter *f, ostream& err)
+{
+  assert(f);
+
+  mds_gid_t gid = gid_from_arg(who, err);
+  if (gid == MDS_GID_NONE) {
+    return -EINVAL;
+  }
+
+  map<mds_gid_t, Metadata> metadata;
+  if (int r = load_metadata(metadata)) {
+    err << "Unable to load 'last_metadata'";
+    return r;
+  }
+
+  if (!metadata.count(gid)) {
+    return -ENOENT;
+  }
+  const Metadata& m = metadata[gid];
+  for (Metadata::const_iterator p = m.begin(); p != m.end(); ++p) {
+    f->dump_string(p->first.c_str(), p->second);
+  }
+  return 0;
+}
+
 void MDSMonitor::tick()
 {
   // make sure mds's are still alive
index 76ef4cf432a5374d6617863018372f433ac59cb2..9b5ccd013721b01c82b503405352b161a3eff0fe 100644 (file)
@@ -130,11 +130,16 @@ public:
   void tick();     // check state, take actions
 
   void dump_info(Formatter *f);
+  int dump_metadata(const string& who, Formatter *f, ostream& err);
 
   void check_subs();
   void check_sub(Subscription *sub);
 
 private:
+  void update_metadata(mds_gid_t gid, const Metadata& metadata);
+  void remove_from_metadata(MonitorDBStore::TransactionRef t);
+  int load_metadata(map<mds_gid_t, Metadata>& m);
+
   // MDS daemon GID to latest health state from that GID
   std::map<uint64_t, MDSHealth> pending_daemon_health;
   std::set<uint64_t> pending_daemon_health_rm;
index 40d26577f092d989bc25db5e96fbbc8871ab48ce..8a8bb320a7bc6621545a4cc6af9d0dc4d991dfa7 100644 (file)
@@ -269,6 +269,9 @@ COMMAND("mds dump "
 COMMAND("mds getmap " \
        "name=epoch,type=CephInt,req=false,range=0", \
        "get MDS map, optionally from epoch", "mds", "r", "cli,rest")
+COMMAND("mds metadata name=who,type=CephString",
+       "fetch metadata for mds <who>",
+       "mds", "r", "cli,rest")
 COMMAND("mds tell " \
        "name=who,type=CephString " \
        "name=args,type=CephString,n=N", \