From: Kefu Chai Date: Thu, 26 Mar 2015 17:08:04 +0000 (+0800) Subject: mon: add "mon_metadata " command X-Git-Tag: v9.0.2~199^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1b0386b2e1eefce84eaca652df116ef3fdd9de4c;p=ceph.git mon: add "mon_metadata " command Related: #10904 Signed-off-by: Kefu Chai --- diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index fab48b53ce7d..03785ce4d3cb 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -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() diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 63922f5654b0..60dedd47d2f5 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -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 diff --git a/src/messages/MMonMetadata.h b/src/messages/MMonMetadata.h new file mode 100644 index 000000000000..6c1896628f83 --- /dev/null +++ b/src/messages/MMonMetadata.h @@ -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 diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 0bfa1fc23e89..40d26577f092 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -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 ", + "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 ", "mon", "rw", "cli,rest") - /* * OSD commands */ diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 8d1b3ee786cd..456dff5a5786 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -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& 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 &q, int l, uint64_t features) @@ -1878,6 +1880,11 @@ void Monitor::lose_election(epoch_t epoch, set &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(m)); break; + case CEPH_MSG_MON_METADATA: + return handle_mon_metadata(static_cast(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 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& 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 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 diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 72f1307602b4..1654bb815c93 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -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& cmdmap, map ¶m_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 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& m); + // features static CompatSet get_initial_supported_features(); static CompatSet get_supported_features(); diff --git a/src/mon/mon_types.h b/src/mon/mon_types.h index d7346cf2de43..4fa97d3a80bc 100644 --- a/src/mon/mon_types.h +++ b/src/mon/mon_types.h @@ -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 Metadata; + #endif diff --git a/src/msg/Message.cc b/src/msg/Message.cc index 23f5179a9e4b..c29ecefdf513 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -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();