1
0
mirror of https://github.com/ceph/ceph synced 2025-04-01 23:02:17 +00:00

mds,mon: add 'mds metadata' command

Related: 
Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2015-03-31 16:36:52 +08:00
parent 73390d2e0c
commit 79439d43a8
7 changed files with 127 additions and 4 deletions

View File

@ -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 //')

View 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);
}

View 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);
}
}
};

View 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),

View 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

View 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;

View 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", \