diff options
Diffstat (limited to 'src/mon/PGMap.cc')
-rw-r--r-- | src/mon/PGMap.cc | 329 |
1 files changed, 323 insertions, 6 deletions
diff --git a/src/mon/PGMap.cc b/src/mon/PGMap.cc index ae19174e4f5..590b2f545ea 100644 --- a/src/mon/PGMap.cc +++ b/src/mon/PGMap.cc @@ -1112,6 +1112,44 @@ void PGMap::dump_stuck_plain(ostream& ss, int types, utime_t cutoff) const dump_pg_stats_plain(ss, stuck_pg_stats, true); } +int PGMap::dump_stuck_pg_stats( + stringstream &ds, + Formatter *f, + int threshold, + vector<string>& args) const +{ + int stuck_types = 0; + + for (vector<string>::iterator i = args.begin(); i != args.end(); ++i) { + if (*i == "inactive") + stuck_types |= PGMap::STUCK_INACTIVE; + else if (*i == "unclean") + stuck_types |= PGMap::STUCK_UNCLEAN; + else if (*i == "undersized") + stuck_types |= PGMap::STUCK_UNDERSIZED; + else if (*i == "degraded") + stuck_types |= PGMap::STUCK_DEGRADED; + else if (*i == "stale") + stuck_types |= PGMap::STUCK_STALE; + else { + ds << "Unknown type: " << *i << std::endl; + return -EINVAL; + } + } + + utime_t now(ceph_clock_now()); + utime_t cutoff = now - utime_t(threshold, 0); + + if (!f) { + dump_stuck_plain(ds, stuck_types, cutoff); + } else { + dump_stuck(f, stuck_types, cutoff); + f->flush(ds); + } + + return 0; +} + void PGMap::dump_osd_perf_stats(Formatter *f) const { f->open_array_section("osd_perf_infos"); @@ -1742,7 +1780,7 @@ void PGMap::generate_test_instances(list<PGMap*>& o) } void PGMap::get_filtered_pg_stats(uint32_t state, int64_t poolid, int64_t osdid, - bool primary, set<pg_t>& pgs) + bool primary, set<pg_t>& pgs) const { for (ceph::unordered_map<pg_t, pg_stat_t>::const_iterator i = pg_stat.begin(); i != pg_stat.end(); @@ -1757,11 +1795,11 @@ void PGMap::get_filtered_pg_stats(uint32_t state, int64_t poolid, int64_t osdid, } } -void PGMap::dump_filtered_pg_stats(Formatter *f, set<pg_t>& pgs) +void PGMap::dump_filtered_pg_stats(Formatter *f, set<pg_t>& pgs) const { f->open_array_section("pg_stats"); for (set<pg_t>::iterator i = pgs.begin(); i != pgs.end(); ++i) { - pg_stat_t& st = pg_stat[*i]; + const pg_stat_t& st = pg_stat.at(*i); f->open_object_section("pg_stat"); f->dump_stream("pgid") << *i; st.dump(f); @@ -1770,7 +1808,7 @@ void PGMap::dump_filtered_pg_stats(Formatter *f, set<pg_t>& pgs) f->close_section(); } -void PGMap::dump_filtered_pg_stats(ostream& ss, set<pg_t>& pgs) +void PGMap::dump_filtered_pg_stats(ostream& ss, set<pg_t>& pgs) const { TextTable tab; @@ -1797,7 +1835,7 @@ void PGMap::dump_filtered_pg_stats(ostream& ss, set<pg_t>& pgs) tab.define_column("DEEP_SCRUB_STAMP", TextTable::LEFT, TextTable::RIGHT); for (set<pg_t>::iterator i = pgs.begin(); i != pgs.end(); ++i) { - pg_stat_t& st = pg_stat[*i]; + const pg_stat_t& st = pg_stat.at(*i); ostringstream reported; reported << st.reported_epoch << ":" << st.reported_seq; @@ -2079,6 +2117,285 @@ void PGMap::dump_object_stat_sum(TextTable &tbl, Formatter *f, } +int process_pg_map_command( + const string& orig_prefix, + const map<string,cmd_vartype>& orig_cmdmap, + const PGMap& pg_map, + const OSDMap& osdmap, + Formatter *f, + stringstream *ss, + bufferlist *odata) +{ + string prefix = orig_prefix; + map<string,cmd_vartype> cmdmap = orig_cmdmap; + + // perhaps these would be better in the parsing, but it's weird + bool primary = false; + if (prefix == "pg dump_json") { + vector<string> v; + v.push_back(string("all")); + cmd_putval(g_ceph_context, cmdmap, "format", string("json")); + cmd_putval(g_ceph_context, cmdmap, "dumpcontents", v); + prefix = "pg dump"; + } else if (prefix == "pg dump_pools_json") { + vector<string> v; + v.push_back(string("pools")); + cmd_putval(g_ceph_context, cmdmap, "format", string("json")); + cmd_putval(g_ceph_context, cmdmap, "dumpcontents", v); + prefix = "pg dump"; + } else if (prefix == "pg ls-by-primary") { + primary = true; + prefix = "pg ls"; + } else if (prefix == "pg ls-by-osd") { + prefix = "pg ls"; + } else if (prefix == "pg ls-by-pool") { + prefix = "pg ls"; + string poolstr; + cmd_getval(g_ceph_context, cmdmap, "poolstr", poolstr); + int64_t pool = osdmap.lookup_pg_pool_name(poolstr.c_str()); + if (pool < 0) { + *ss << "pool " << poolstr << " does not exist"; + return -ENOENT; + } + cmd_putval(g_ceph_context, cmdmap, "pool", pool); + } + + int r = 0; + stringstream ds; + if (prefix == "pg stat") { + if (f) { + f->open_object_section("pg_summary"); + pg_map.print_oneline_summary(f, NULL); + f->close_section(); + f->flush(ds); + } else { + ds << pg_map; + } + odata->append(ds); + return 0; + } + + if (prefix == "pg getmap") { + pg_map.encode(*odata); + *ss << "got pgmap version " << pg_map.version; + return 0; + } + + if (prefix == "pg dump") { + string val; + vector<string> dumpcontents; + set<string> what; + if (cmd_getval(g_ceph_context, cmdmap, "dumpcontents", dumpcontents)) { + copy(dumpcontents.begin(), dumpcontents.end(), + inserter(what, what.end())); + } + if (what.empty()) + what.insert("all"); + if (f) { + if (what.count("all")) { + f->open_object_section("pg_map"); + pg_map.dump(f); + f->close_section(); + } else if (what.count("summary") || what.count("sum")) { + f->open_object_section("pg_map"); + pg_map.dump_basic(f); + f->close_section(); + } else { + if (what.count("pools")) { + pg_map.dump_pool_stats(f); + } + if (what.count("osds")) { + pg_map.dump_osd_stats(f); + } + if (what.count("pgs")) { + pg_map.dump_pg_stats(f, false); + } + if (what.count("pgs_brief")) { + pg_map.dump_pg_stats(f, true); + } + if (what.count("delta")) { + f->open_object_section("delta"); + pg_map.dump_delta(f); + f->close_section(); + } + } + f->flush(*odata); + } else { + if (what.count("all")) { + pg_map.dump(ds); + } else if (what.count("summary") || what.count("sum")) { + pg_map.dump_basic(ds); + pg_map.dump_pg_sum_stats(ds, true); + pg_map.dump_osd_sum_stats(ds); + } else { + if (what.count("pgs_brief")) { + pg_map.dump_pg_stats(ds, true); + } + bool header = true; + if (what.count("pgs")) { + pg_map.dump_pg_stats(ds, false); + header = false; + } + if (what.count("pools")) { + pg_map.dump_pool_stats(ds, header); + } + if (what.count("osds")) { + pg_map.dump_osd_stats(ds); + } + } + odata->append(ds); + } + *ss << "dumped " << what; + return 0; + } + + if (prefix == "pg ls") { + int64_t osd = -1; + int64_t pool = -1; + vector<string>states; + set<pg_t> pgs; + cmd_getval(g_ceph_context, cmdmap, "pool", pool); + cmd_getval(g_ceph_context, cmdmap, "osd", osd); + cmd_getval(g_ceph_context, cmdmap, "states", states); + if (pool >= 0 && !osdmap.have_pg_pool(pool)) { + *ss << "pool " << pool << " does not exist"; + return -ENOENT; + } + if (osd >= 0 && !osdmap.is_up(osd)) { + *ss << "osd " << osd << " is not up"; + return -EAGAIN; + } + if (states.empty()) + states.push_back("all"); + + uint32_t state = 0; + + while (!states.empty()) { + string state_str = states.back(); + + if (state_str == "all") { + state = -1; + break; + } else { + int filter = pg_string_state(state_str); + assert(filter != -1); + state |= filter; + } + + states.pop_back(); + } + + pg_map.get_filtered_pg_stats(state, pool, osd, primary, pgs); + + if (f && !pgs.empty()) { + pg_map.dump_filtered_pg_stats(f, pgs); + f->flush(*odata); + } else if (!pgs.empty()) { + pg_map.dump_filtered_pg_stats(ds, pgs); + odata->append(ds); + } + return 0; + } + + if (prefix == "pg dump_stuck") { + vector<string> stuckop_vec; + cmd_getval(g_ceph_context, cmdmap, "stuckops", stuckop_vec); + if (stuckop_vec.empty()) + stuckop_vec.push_back("unclean"); + int64_t threshold; + cmd_getval(g_ceph_context, cmdmap, "threshold", threshold, + int64_t(g_conf->mon_pg_stuck_threshold)); + + r = pg_map.dump_stuck_pg_stats(ds, f, (int)threshold, stuckop_vec); + odata->append(ds); + if (r < 0) + *ss << "failed"; + else + *ss << "ok"; + return 0; + } + + if (prefix == "pg map") { + pg_t pgid; + string pgidstr; + cmd_getval(g_ceph_context, cmdmap, "pgid", pgidstr); + if (!pgid.parse(pgidstr.c_str())) { + *ss << "invalid pgid '" << pgidstr << "'"; + return -EINVAL; + } + vector<int> up, acting; + if (!osdmap.have_pg_pool(pgid.pool())) { + *ss << "pg '" << pgidstr << "' does not exist"; + return -ENOENT; + } + pg_t mpgid = osdmap.raw_pg_to_pg(pgid); + osdmap.pg_to_up_acting_osds(pgid, up, acting); + if (f) { + f->open_object_section("pg_map"); + f->dump_unsigned("epoch", osdmap.get_epoch()); + f->dump_stream("raw_pgid") << pgid; + f->dump_stream("pgid") << mpgid; + + f->open_array_section("up"); + for (vector<int>::iterator it = up.begin(); it != up.end(); ++it) + f->dump_int("up_osd", *it); + f->close_section(); + + f->open_array_section("acting"); + for (vector<int>::iterator it = acting.begin(); it != acting.end(); ++it) + f->dump_int("acting_osd", *it); + f->close_section(); + + f->close_section(); + f->flush(*odata); + } else { + ds << "osdmap e" << osdmap.get_epoch() + << " pg " << pgid << " (" << mpgid << ")" + << " -> up " << up << " acting " << acting; + odata->append(ds); + } + return 0; + } + + if (prefix == "pg debug") { + string debugop; + cmd_getval(g_ceph_context, cmdmap, "debugop", debugop, + string("unfound_objects_exist")); + if (debugop == "unfound_objects_exist") { + bool unfound_objects_exist = false; + for (const auto& p : pg_map.pg_stat) { + if (p.second.stats.sum.num_objects_unfound > 0) { + unfound_objects_exist = true; + break; + } + } + if (unfound_objects_exist) + ds << "TRUE"; + else + ds << "FALSE"; + odata->append(ds); + return 0; + } + if (debugop == "degraded_pgs_exist") { + bool degraded_pgs_exist = false; + for (const auto& p : pg_map.pg_stat) { + if (p.second.stats.sum.num_objects_degraded > 0) { + degraded_pgs_exist = true; + break; + } + } + if (degraded_pgs_exist) + ds << "TRUE"; + else + ds << "FALSE"; + odata->append(ds); + return 0; + } + } + + return -EOPNOTSUPP; +} + void PGMapUpdater::check_osd_map(const OSDMap::Incremental &osd_inc, std::set<int> *need_check_down_pg_osds, std::map<int,utime_t> *last_osd_report, @@ -2175,7 +2492,7 @@ void PGMapUpdater::register_pg( stats.last_deep_scrub_stamp = ps.last_deep_scrub_stamp; stats.last_clean_scrub_stamp = ps.last_clean_scrub_stamp; } else { - utime_t now = ceph_clock_now(); + utime_t now = osd_map.get_modified(); stats.last_fresh = now; stats.last_active = now; stats.last_change = now; |