From 79439d43a87b86f4e5e899215c6ddba7ac27fef7 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 31 Mar 2015 16:36:52 +0800 Subject: [PATCH] mds,mon: add 'mds metadata' command Related: #10904 Signed-off-by: Kefu Chai --- qa/workunits/cephtool/test.sh | 3 ++ src/mds/Beacon.cc | 8 ++- src/messages/MMDSBeacon.h | 14 ++++- src/messages/MMonMetadata.h | 2 +- src/mon/MDSMonitor.cc | 96 ++++++++++++++++++++++++++++++++++- src/mon/MDSMonitor.h | 5 ++ src/mon/MonCommands.h | 3 ++ 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index 03785ce4d3cb6..b4b41f83a9066 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -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 //') diff --git a/src/mds/Beacon.cc b/src/mds/Beacon.cc index 35265db52303f..cc7fa2bdce1c0 100644 --- a/src/mds/Beacon.cc +++ b/src/mds/Beacon.cc @@ -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 sys_info; + collect_sys_info(&sys_info, cct); + beacon->set_sys_info(sys_info); + } monc->send_mon_message(beacon); } diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h index ab53760ace4ec..da551f4e04010 100644 --- a/src/messages/MMDSBeacon.h +++ b/src/messages/MMDSBeacon.h @@ -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 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& get_sys_info() const { return sys_info; } + void set_sys_info(const map& 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); + } } }; diff --git a/src/messages/MMonMetadata.h b/src/messages/MMonMetadata.h index 6c1896628f834..ae56611517cf9 100644 --- a/src/messages/MMonMetadata.h +++ b/src/messages/MMonMetadata.h @@ -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), diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index f5d2b3d7eb04d..c79094a45f03c 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -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::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& metadata) +{ + if (metadata.empty()) { + return; + } + bufferlist bl; + int err = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl); + map 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 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::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& 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 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 diff --git a/src/mon/MDSMonitor.h b/src/mon/MDSMonitor.h index 76ef4cf432a53..9b5ccd013721b 100644 --- a/src/mon/MDSMonitor.h +++ b/src/mon/MDSMonitor.h @@ -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& m); + // MDS daemon GID to latest health state from that GID std::map pending_daemon_health; std::set pending_daemon_health_rm; diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 40d26577f092d..8a8bb320a7bc6 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -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 ", + "mds", "r", "cli,rest") COMMAND("mds tell " \ "name=who,type=CephString " \ "name=args,type=CephString,n=N", \ -- 2.39.5