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 //')
#include "common/dout.h"
#include "common/HeartbeatMap.h"
#include "include/stringify.h"
+#include "include/util.h"
#include "messages/MMDSBeacon.h"
#include "mon/MonClient.h"
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);
}
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;
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) :
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 << ")";
::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();
if (header.version >= 3) {
::decode(health, p);
}
+ if (state == MDSMap::STATE_BOOT &&
+ header.version >= 4) {
+ ::decode(sys_info, p);
+ }
}
};
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),
return cmd_getval(cct, cmdmap, k, (int64_t&)val);
}
-
+static const string MDS_METADATA_PREFIX("mds_metadata");
// my methods
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();
}
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);
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;
}
}
+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
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;
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", \