mon: add "mon_metadata <id>" command

Related: #10904
Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2015-03-27 01:08:04 +08:00
parent 0e3bee688e
commit 1b0386b2e1
8 changed files with 163 additions and 5 deletions

View File

@ -563,6 +563,8 @@ function test_mon_misc()
mymsg="this is a test log message $$.$(date)"
ceph log "$mymsg"
ceph_watch_wait "$mymsg"
ceph mon_metadata a
}
function check_mds_active()

View File

@ -94,6 +94,7 @@ struct ceph_dir_layout {
#define CEPH_MSG_MON_MAP 4
#define CEPH_MSG_MON_GET_MAP 5
#define CEPH_MSG_MON_GET_OSDMAP 6
#define CEPH_MSG_MON_METADATA 7
#define CEPH_MSG_STATFS 13
#define CEPH_MSG_STATFS_REPLY 14
#define CEPH_MSG_MON_SUBSCRIBE 15

View File

@ -0,0 +1,52 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2015 Red Hat
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#ifndef CEPH_MMONMETADATA_H
#define CEPH_MMONMETADATA_H
#include "mon/mon_types.h"
#include "msg/Message.h"
class MMonMetadata : public Message {
public:
Metadata data;
private:
static const int HEAD_VERSION = 1;
~MMonMetadata() {}
public:
MMonMetadata() :
Message(CEPH_MSG_MON_METADATA, HEAD_VERSION)
{}
MMonMetadata(const Metadata& metadata) :
Message(CEPH_MSG_MON_METADATA, HEAD_VERSION),
data(metadata)
{}
virtual const char *get_type_name() const {
return "mon_metadata";
}
virtual void encode_payload(uint64_t features) {
::encode(data, payload);
}
virtual void decode_payload() {
bufferlist::iterator p = payload.begin();
::decode(data, p);
}
};
#endif

View File

@ -235,6 +235,10 @@ COMMAND("report name=tags,type=CephString,n=N,req=false", \
"mon", "r", "cli,rest")
COMMAND("quorum_status", "report status of monitor quorum", \
"mon", "r", "cli,rest")
COMMAND("mon_metadata name=id,type=CephString",
"fetch metadata for mon <id>",
"mon", "r", "cli,rest")
COMMAND_WITH_FLAG("mon_status", "report status of monitors", "mon", "r", "cli,rest",
NOFORWARD)
COMMAND("sync force " \
@ -361,7 +365,6 @@ COMMAND("mon remove " \
"name=name,type=CephString", \
"remove monitor named <name>", "mon", "rw", "cli,rest")
/*
* OSD commands
*/

View File

@ -36,6 +36,7 @@
#include "messages/MGenericMessage.h"
#include "messages/MMonCommand.h"
#include "messages/MMonCommandAck.h"
#include "messages/MMonMetadata.h"
#include "messages/MMonSync.h"
#include "messages/MMonScrub.h"
#include "messages/MMonProbe.h"
@ -287,10 +288,9 @@ void Monitor::do_admin_command(string command, cmdmap_t& cmdmap, string format,
}
args = "[" + args + "]";
bool read_only = false;
if (command == "mon_status" || command == "quorum_status") {
read_only = true;
}
bool read_only = (command == "mon_status" ||
command == "mon_metadata" ||
command == "quorum_status");
(read_only ? audit_clog->debug() : audit_clog->info())
<< "from='admin socket' entity='admin socket' "
@ -738,6 +738,7 @@ int Monitor::init()
// i'm ready!
messenger->add_dispatcher_tail(this);
bootstrap();
// encode command sets
@ -1857,6 +1858,7 @@ void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features,
health_tick_start();
do_health_to_clog_interval();
}
collect_sys_info(&metadata[rank], g_ceph_context);
}
void Monitor::lose_election(epoch_t epoch, set<int> &q, int l, uint64_t features)
@ -1878,6 +1880,11 @@ void Monitor::lose_election(epoch_t epoch, set<int> &q, int l, uint64_t features
logger->inc(l_mon_election_lose);
finish_election();
Metadata sys_info;
collect_sys_info(&sys_info, g_ceph_context);
messenger->send_message(new MMonMetadata(sys_info),
monmap->get_inst(get_leader()));
}
void Monitor::finish_election()
@ -2837,6 +2844,23 @@ void Monitor::handle_command(MMonCommand *m)
ss2 << "report " << rdata.crc32c(6789);
rs = ss2.str();
r = 0;
} else if (prefix == "mon_metadata") {
string name;
cmd_getval(g_ceph_context, cmdmap, "id", name);
int mon = monmap->get_rank(name);
if (mon < 0) {
rs = "requested mon not found";
r = -ENOENT;
goto out;
}
if (!f)
f.reset(Formatter::create("json-pretty"));
f->open_object_section("mon_metadata");
r = get_mon_metadata(mon, f.get(), ds);
f->close_section();
f->flush(ds);
rdata.append(ds);
rs = "";
} else if (prefix == "quorum_status") {
// make sure our map is readable and up to date
if (!is_leader() && !is_peon()) {
@ -3411,6 +3435,9 @@ void Monitor::dispatch(MonSession *s, Message *m, const bool src_is_mon)
handle_mon_get_map(static_cast<MMonGetMap*>(m));
break;
case CEPH_MSG_MON_METADATA:
return handle_mon_metadata(static_cast<MMonMetadata*>(m));
default:
dealt_with = false;
break;
@ -4185,7 +4212,64 @@ void Monitor::handle_mon_get_map(MMonGetMap *m)
m->put();
}
void Monitor::handle_mon_metadata(MMonMetadata *m)
{
if (is_leader()) {
dout(10) << __func__ << dendl;
update_mon_metadata(m->get_source().num(), m->data);
}
m->put();
}
void Monitor::update_mon_metadata(int from, const Metadata& m)
{
metadata[from] = m;
bufferlist bl;
int err = store->get(MONITOR_STORE_PREFIX, "last_metadata", bl);
map<int, Metadata> last_metadata;
if (!err) {
bufferlist::iterator iter = bl.begin();
::decode(last_metadata, iter);
metadata.insert(last_metadata.begin(), last_metadata.end());
}
MonitorDBStore::TransactionRef t = paxos->get_pending_transaction();
bl.clear();
::encode(metadata, bl);
t->put(MONITOR_STORE_PREFIX, "last_metadata", bl);
paxos->trigger_propose();
}
int Monitor::load_metadata(map<int, Metadata>& metadata)
{
bufferlist bl;
int r = store->get(MONITOR_STORE_PREFIX, "last_metadata", bl);
if (r)
return r;
bufferlist::iterator it = bl.begin();
::decode(metadata, it);
return 0;
}
int Monitor::get_mon_metadata(int mon, Formatter *f, ostream& err)
{
assert(f);
map<int, Metadata> last_metadata;
if (int r = load_metadata(last_metadata)) {
err << "Unable to load metadata";
return r;
}
if (!last_metadata.count(mon)) {
err << "mon." << mon << " not found";
return -EINVAL;
}
const Metadata& m = last_metadata[mon];
for (Metadata::const_iterator p = m.begin(); p != m.end(); ++p) {
f->dump_string(p->first.c_str(), p->second);
}
return 0;
}
// ----------------------------------------------
// scrub

View File

@ -107,6 +107,7 @@ class AdminSocketHook;
class MMonGetMap;
class MMonGetVersion;
class MMonMetadata;
class MMonSync;
class MMonScrub;
class MMonProbe;
@ -637,6 +638,7 @@ public:
void handle_get_version(MMonGetVersion *m);
void handle_subscribe(MMonSubscribe *m);
void handle_mon_get_map(MMonGetMap *m);
static void _generate_command_map(map<string,cmd_vartype>& cmdmap,
map<string,string> &param_str_map);
static const MonCommand *_get_moncommand(const string &cmd_prefix,
@ -651,6 +653,10 @@ public:
void handle_command(class MMonCommand *m);
void handle_route(MRoute *m);
void handle_mon_metadata(MMonMetadata *m);
int get_mon_metadata(int mon, Formatter *f, ostream& err);
map<int, Metadata> metadata;
/**
*
*/
@ -847,6 +853,9 @@ public:
int write_default_keyring(bufferlist& bl);
void extract_save_mon_key(KeyRing& keyring);
void update_mon_metadata(int from, const Metadata& m);
int load_metadata(map<int, Metadata>& m);
// features
static CompatSet get_initial_supported_features();
static CompatSet get_supported_features();

View File

@ -203,4 +203,7 @@ static inline ostream& operator<<(ostream& out, const ScrubResult& r) {
return out << "ScrubResult(keys " << r.prefix_keys << " crc " << r.prefix_crc << ")";
}
/// for information like os, kernel, hostname, memory info, cpu model.
typedef map<string, string> Metadata;
#endif

View File

@ -90,6 +90,7 @@ using namespace std;
#include "messages/MMonGetVersion.h"
#include "messages/MMonGetVersionReply.h"
#include "messages/MMonHealth.h"
#include "messages/MMonMetadata.h"
#include "messages/MDataPing.h"
#include "messages/MAuth.h"
#include "messages/MAuthReply.h"
@ -396,6 +397,9 @@ Message *decode_message(CephContext *cct, int crcflags,
case CEPH_MSG_MON_GET_VERSION_REPLY:
m = new MMonGetVersionReply();
break;
case CEPH_MSG_MON_METADATA:
m = new MMonMetadata();
break;
case MSG_OSD_BOOT:
m = new MOSDBoot();