for (const auto& q : pgmap.pg_stat) {
set<int32_t> pg_acting; // net acting sets (with no missing if degraded)
bool found = false;
+ if (q.second.state == 0) {
+ report->unknown.insert(q.first);
+ continue;
+ }
if (q.second.state & PG_STATE_DEGRADED) {
for (auto& anm : q.second.avail_no_missing) {
if (osds.count(anm.osd)) {
}
}
dout(20) << osds << " -> " << report->ok.size() << " ok, "
- << report->not_ok.size() << " not ok" << dendl;
+ << report->not_ok.size() << " not ok, "
+ << report->unknown.size() << " unknown"
+ << dendl;
}
void DaemonServer::_maximize_ok_to_stop_set(
}
offline_pg_report out_report;
cluster_state.with_osdmap_and_pgmap([&](const OSDMap& osdmap, const PGMap& pg_map) {
- if (pg_map.num_pg_unknown > 0) {
- ss << pg_map.num_pg_unknown << " pgs have unknown state; "
- << "cannot draw any conclusions";
- r = -EAGAIN;
- return;
- }
_maximize_ok_to_stop_set(
osds, max, osdmap, pg_map,
&out_report);
});
- if (r < 0) {
- cmdctx->reply(r, ss);
- return true;
- }
if (!f) {
f.reset(Formatter::create("json"));
}
f->dump_object("ok_to_stop", out_report);
f->flush(cmdctx->odata);
cmdctx->odata.append("\n");
+ if (!out_report.unknown.empty()) {
+ ss << out_report.unknown.size() << " pgs have unknown state; "
+ << "cannot draw any conclusions";
+ cmdctx->reply(-EAGAIN, ss);
+ }
if (!out_report.ok_to_stop()) {
ss << "unsafe to stop osd(s)";
cmdctx->reply(-EBUSY, ss);
struct offline_pg_report {
set<int> osds;
- set<pg_t> ok, not_ok;
+ set<pg_t> ok, not_ok, unknown;
set<pg_t> ok_become_degraded, ok_become_more_degraded; // ok
set<pg_t> bad_no_pool, bad_already_inactive, bad_become_inactive; // not ok
bool ok_to_stop() const {
- return not_ok.empty();
+ return not_ok.empty() && unknown.empty();
}
void dump(Formatter *f) const {
f->dump_unsigned("num_ok_pgs", ok.size());
f->dump_unsigned("num_not_ok_pgs", not_ok.size());
+ // ambiguous
+ if (!unknown.empty()) {
+ f->open_array_section("unknown_pgs");
+ for (auto pg : unknown) {
+ f->dump_stream("pg") << pg;
+ }
+ f->close_section();
+ }
+
// bad news
if (!bad_no_pool.empty()) {
f->open_array_section("bad_no_pool_pgs");