"telemetry",
}
},
+ {
+ CEPH_RELEASE_REEF, {
+ "crash",
+ "status",
+ "progress",
+ "balancer",
+ "devicehealth",
+ "orchestrator",
+ "rbd_support",
+ "volumes",
+ "pg_autoscaler",
+ "telemetry",
+ }
+ },
};
// Prefix for mon store of active mgr's command descriptions
} catch (const bad_cmd_get& e) {
bufferlist bl;
mon.reply_command(op, -EINVAL, e.what(), bl, get_last_committed());
- return true;
+ return false; /* nothing to propose! */
}
default:
mon.no_reply(op);
derr << "Unhandled message type " << m->get_type() << dendl;
- return true;
+ return false; /* nothing to propose! */
}
}
auto m = op->get_req<MMgrBeacon>();
dout(4) << "beacon from " << m->get_gid() << dendl;
+ // Track whether we modified pending_map
+ bool updated = false;
+ bool plugged = false;
+
// See if we are seeing same name, new GID for the active daemon
if (m->get_name() == pending_map.active_name
&& m->get_gid() != pending_map.active_gid)
mon.osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
return false;
}
- drop_active();
+ plugged |= drop_active();
+ updated = true;
}
// See if we are seeing same name, new GID for any standbys
mon.clog->debug() << "Standby manager daemon " << m->get_name()
<< " restarted";
drop_standby(i.first);
+ updated = true;
break;
}
}
last_beacon[m->get_gid()] = ceph::coarse_mono_clock::now();
- // Track whether we modified pending_map
- bool updated = false;
-
if (pending_map.active_gid == m->get_gid()) {
if (pending_map.services != m->get_services()) {
dout(4) << "updated services from mgr." << m->get_name()
pending_map.clients = clients;
updated = true;
}
+ } else if (m->get_available()) {
+ dout(4) << "mgr thinks it is active but it is not, dropping!" << dendl;
+ auto m = make_message<MMgrMap>(MgrMap::create_null_mgrmap());
+ mon.send_reply(op, m.detach());
+ goto out;
} else if (pending_map.active_gid == 0) {
// There is no currently active daemon, select this one.
if (pending_map.standbys.count(m->get_gid())) {
dout(10) << "no change" << dendl;
}
+out:
+
+ if (plugged) {
+ paxos.unplug();
+ }
+
return updated;
}
}
bool propose = false;
+ bool plugged = false;
for (auto i : dead_standbys) {
dout(4) << "Dropping laggy standby " << i << dendl;
&& last_beacon.at(pending_map.active_gid) < cutoff
&& mon.osdmon()->is_writeable()) {
const std::string old_active_name = pending_map.active_name;
- drop_active();
+ plugged |= drop_active();
propose = true;
dout(4) << "Dropping active" << pending_map.active_gid << dendl;
if (promote_standby()) {
if (propose) {
propose_pending();
}
+ if (plugged) {
+ paxos.unplug();
+ ceph_assert(propose);
+ paxos.trigger_propose();
+ }
}
void MgrMonitor::on_restart()
}
}
-void MgrMonitor::drop_active()
+bool MgrMonitor::drop_active()
{
ceph_assert(mon.osdmon()->is_writeable());
+ bool plugged = false;
+ if (!paxos.is_plugged()) {
+ paxos.plug();
+ plugged = true;
+ }
+
if (last_beacon.count(pending_map.active_gid) > 0) {
last_beacon.erase(pending_map.active_gid);
}
/* blocklist RADOS clients in use by the mgr */
for (const auto& a : pending_map.clients) {
- mon.osdmon()->blocklist(a, until);
+ mon.osdmon()->blocklist(a.second, until);
}
request_proposal(mon.osdmon());
pending_map.clients.clear();
pending_map.last_failure_osd_epoch = blocklist_epoch;
+ /* If we are dropping the active, we need to notify clients immediately.
+ * Additionally, avoid logical races with ::prepare_beacon which cannot
+ * accurately determine if a mgr is a standby or an old active.
+ */
+ force_immediate_propose();
+
// So that when new active mgr subscribes to mgrdigest, it will
// get an immediate response instead of waiting for next timer
cancel_timer();
+ return plugged;
}
void MgrMonitor::drop_standby(uint64_t gid, bool drop_meta)
string format = cmd_getval_or<string>(cmdmap, "format", "plain");
boost::scoped_ptr<Formatter> f(Formatter::create(format));
- string prefix;
- cmd_getval(cmdmap, "prefix", prefix);
-
+ const auto prefix = cmd_getval_or<string>(cmdmap, "prefix", string{});
int r = 0;
+ bool plugged = false;
if (prefix == "mgr fail") {
string who;
mon.osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
return false;
}
- drop_active();
+ plugged |= drop_active();
changed = true;
} else {
gid = 0;
mon.osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
return false;
}
- drop_active();
+ plugged |= drop_active();
changed = true;
} else if (pending_map.standbys.count(gid) > 0) {
drop_standby(gid);
// success.. delay reply
wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, r, rs,
get_last_committed() + 1));
- return true;
} else {
// reply immediately
mon.reply_command(op, r, rs, rdata, get_last_committed());
- return false;
}
+
+ if (plugged) {
+ paxos.unplug();
+ }
+
+ return r >= 0;
}
void MgrMonitor::init()