From 71bf5f1eb37acab74c2688be320619bcd9795d67 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 31 Mar 2015 23:41:53 +0800 Subject: [PATCH] mon: add 'node ls {all,mds,mon,osd}' asok Fixes: #10904 Signed-off-by: Kefu Chai --- qa/workunits/cephtool/test.sh | 5 ++++ src/common/util.cc | 18 ++++++++++++++ src/include/util.h | 6 +++++ src/mon/MDSMonitor.cc | 28 +++++++++++++++++++++ src/mon/MDSMonitor.h | 1 + src/mon/MonCommands.h | 4 ++- src/mon/Monitor.cc | 46 +++++++++++++++++++++++++++++++++++ src/mon/Monitor.h | 1 + src/mon/OSDMonitor.cc | 31 +++++++++++++++++++++-- src/mon/OSDMonitor.h | 3 +++ 10 files changed, 140 insertions(+), 3 deletions(-) diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index b4b41f83a9066..2784eabadab0c 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -559,6 +559,11 @@ function test_mon_misc() ceph health --format json-pretty ceph health detail --format xml-pretty + ceph node ls + for t in mon osd mds ; do + ceph node ls $t + done + ceph_watch_start mymsg="this is a test log message $$.$(date)" ceph log "$mymsg" diff --git a/src/common/util.cc b/src/common/util.cc index 13132f5e8f9fd..3c3a304c22fcb 100644 --- a/src/common/util.cc +++ b/src/common/util.cc @@ -235,3 +235,21 @@ void collect_sys_info(map *m, CephContext *cct) // distro info lsb_release_parse(m, cct); } + +void dump_services(Formatter* f, const map >& services, const char* type) +{ + assert(f); + + f->open_object_section(type); + for (map >::const_iterator host = services.begin(); + host != services.end(); ++host) { + f->open_array_section(host->first.c_str()); + const list& hosted = host->second; + for (list::const_iterator s = hosted.begin(); + s != hosted.end(); ++s) { + f->dump_int(type, *s); + } + f->close_section(); + } + f->close_section(); +} diff --git a/src/include/util.h b/src/include/util.h index c3a28bc443eec..c453440dc1b64 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -79,4 +79,10 @@ int get_fs_stats(ceph_data_stats_t &stats, const char *path); /// collect info from @p uname(2), @p /proc/meminfo and @p /proc/cpuinfo void collect_sys_info(map *m, CephContext *cct); +/// dump service ids grouped by their host to the specified formatter +/// @param f formatter for the output +/// @param services a map from hostname to a list of service id hosted by this host +/// @param type the service type of given @p services, for example @p osd or @p mon. +void dump_services(Formatter* f, const map >& services, const char* type); + #endif /* CEPH_UTIL_H */ diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index c79094a45f03c..34d18d5bfb78b 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -1792,6 +1792,34 @@ int MDSMonitor::dump_metadata(const std::string &who, Formatter *f, ostream& err return 0; } +int MDSMonitor::print_nodes(Formatter *f) +{ + assert(f); + + map metadata; + if (int r = load_metadata(metadata)) { + return r; + } + + map > mdses; // hostname => rank + for (map::iterator it = metadata.begin(); + it != metadata.end(); ++it) { + const Metadata& m = it->second; + Metadata::const_iterator hostname = m.find("hostname"); + if (hostname == m.end()) { + // not likely though + continue; + } + const mds_gid_t gid = it->first; + assert(mdsmap.get_state_gid(gid) != MDSMap::STATE_NULL); + const MDSMap::mds_info_t& mds_info = mdsmap.get_info_gid(gid); + mdses[hostname->second].push_back(mds_info.rank); + } + + dump_services(f, mdses, "mds"); + 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 9b5ccd013721b..88bf69a48fc7d 100644 --- a/src/mon/MDSMonitor.h +++ b/src/mon/MDSMonitor.h @@ -131,6 +131,7 @@ public: void dump_info(Formatter *f); int dump_metadata(const string& who, Formatter *f, ostream& err); + int print_nodes(Formatter *f); void check_subs(); void check_sub(Subscription *sub); diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 8a8bb320a7bc6..4bde698fb04d3 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -257,7 +257,9 @@ COMMAND("tell " \ "send a command to a specific daemon", "mon", "rw", "cli,rest") COMMAND_WITH_FLAG("version", "show mon daemon version", "mon", "r", "cli,rest", NOFORWARD) - +COMMAND("node ls " \ + "name=type,type=CephChoices,strings=all|osd|mon|mds,req=false", + "list all nodes in cluster [type]", "mon", "r", "cli,rest") /* * MDS commands (MDSMonitor.cc) */ diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 456dff5a57862..74ba6a11211ef 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -2844,6 +2844,28 @@ void Monitor::handle_command(MMonCommand *m) ss2 << "report " << rdata.crc32c(6789); rs = ss2.str(); r = 0; + } else if (prefix == "node ls") { + string node_type("all"); + cmd_getval(g_ceph_context, cmdmap, "type", node_type); + if (!f) + f.reset(Formatter::create("json-pretty")); + if (node_type == "all") { + f->open_object_section("nodes"); + print_nodes(f.get(), ds); + osdmon()->print_nodes(f.get()); + mdsmon()->print_nodes(f.get()); + f->close_section(); + } else if (node_type == "mon") { + print_nodes(f.get(), ds); + } else if (node_type == "osd") { + osdmon()->print_nodes(f.get()); + } else if (node_type == "mds") { + mdsmon()->print_nodes(f.get()); + } + f->flush(ds); + rdata.append(ds); + rs = ""; + r = 0; } else if (prefix == "mon_metadata") { string name; cmd_getval(g_ceph_context, cmdmap, "id", name); @@ -4271,6 +4293,30 @@ int Monitor::get_mon_metadata(int mon, Formatter *f, ostream& err) return 0; } +int Monitor::print_nodes(Formatter *f, ostream& err) +{ + map metadata; + if (int r = load_metadata(metadata)) { + err << "Unable to load metadata.\n"; + return r; + } + + map > mons; // hostname => mon + for (map::iterator it = metadata.begin(); + it != metadata.end(); ++it) { + const Metadata& m = it->second; + Metadata::const_iterator hostname = m.find("hostname"); + if (hostname == m.end()) { + // not likely though + continue; + } + mons[hostname->second].push_back(it->first); + } + + dump_services(f, mons, "mon"); + return 0; +} + // ---------------------------------------------- // scrub diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 1654bb815c931..d031115167bf9 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -655,6 +655,7 @@ public: void handle_mon_metadata(MMonMetadata *m); int get_mon_metadata(int mon, Formatter *f, ostream& err); + int print_nodes(Formatter *f, ostream& err); map metadata; /** diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 9f44a479ed6a0..c586b41ba20b7 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -1124,13 +1124,12 @@ void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t) pending_metadata_rm.clear(); } -int OSDMonitor::dump_osd_metadata(int osd, Formatter *f, ostream *err) +int OSDMonitor::load_metadata(int osd, map& m, ostream *err) { bufferlist bl; int r = mon->store->get(OSD_METADATA_PREFIX, stringify(osd), bl); if (r < 0) return r; - map m; try { bufferlist::iterator p = bl.begin(); ::decode(m, p); @@ -1140,11 +1139,39 @@ int OSDMonitor::dump_osd_metadata(int osd, Formatter *f, ostream *err) *err << "osd." << osd << " metadata is corrupt"; return -EIO; } + return 0; +} + +int OSDMonitor::dump_osd_metadata(int osd, Formatter *f, ostream *err) +{ + map m; + if (int r = load_metadata(osd, m, err)) + return r; for (map::iterator p = m.begin(); p != m.end(); ++p) f->dump_string(p->first.c_str(), p->second); return 0; } +void OSDMonitor::print_nodes(Formatter *f) +{ + // group OSDs by their hosts + map > osds; // hostname => osd + for (int osd = 0; osd <= osdmap.get_max_osd(); osd++) { + map m; + if (load_metadata(osd, m, NULL)) { + continue; + } + map::iterator hostname = m.find("hostname"); + if (hostname == m.end()) { + // not likely though + continue; + } + osds[hostname->second].push_back(osd); + } + + dump_services(f, osds, "osd"); +} + void OSDMonitor::share_map_with_random_osd() { if (osdmap.get_num_up_osds() == 0) { diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h index 1e7f8f0bcff3f..41cd805a7e2d4 100644 --- a/src/mon/OSDMonitor.h +++ b/src/mon/OSDMonitor.h @@ -386,6 +386,8 @@ private: bool preprocess_remove_snaps(struct MRemoveSnaps *m); bool prepare_remove_snaps(struct MRemoveSnaps *m); + int load_metadata(int osd, map& m, ostream *err); + public: OSDMonitor(Monitor *mn, Paxos *p, string service_name) : PaxosService(mn, p, service_name), @@ -418,6 +420,7 @@ private: void dump_info(Formatter *f); int dump_osd_metadata(int osd, Formatter *f, ostream *err); + void print_nodes(Formatter *f); void check_subs(); void check_sub(Subscription *sub); -- 2.39.5