.add_service("mon")
.set_description("force mons to trim mdsmaps/fsmaps through this epoch"),
+ Option("mds_beacon_mon_down_grace", Option::TYPE_SECS, Option::LEVEL_ADVANCED)
+ .set_default(1_min)
+ .set_description("tolerance in seconds for missed MDS beacons to monitors")
+ .set_long_description("The interval without beacons before Ceph declares an MDS laggy when a monitor is down."),
+
Option("mon_mds_skip_sanity", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
.set_default(false)
.add_service("mon")
// check beacon timestamps
std::vector<mds_gid_t> to_remove;
+ const bool mon_down = mon.is_mon_down();
+ const auto mds_beacon_mon_down_grace =
+ g_conf().get_val<std::chrono::seconds>("mds_beacon_mon_down_grace");
+ const auto quorum_age = std::chrono::seconds(mon.quorum_age());
+ const bool new_quorum = quorum_age < mds_beacon_mon_down_grace;
for (auto it = last_beacon.begin(); it != last_beacon.end(); ) {
auto& [gid, beacon_info] = *it;
auto since_last = std::chrono::duration<double>(now-beacon_info.stamp);
<< " (gid: " << gid << " addr: " << info.addrs
<< " state: " << ceph_mds_state_name(info.state) << ")"
<< " since " << since_last.count() << dendl;
+ if ((mon_down || new_quorum) && since_last < mds_beacon_mon_down_grace) {
+ /* The MDS may be sending beacons to a monitor not yet in quorum or
+ * temporarily partitioned. Hold off on removal for a little longer...
+ */
+ dout(10) << "deferring removal for mds_beacon_mon_down_grace during MON_DOWN" << dendl;
+ ++it;
+ continue;
+ }
// If the OSDMap is writeable, we can blocklist things, so we can
// try failing any laggy MDS daemons. Consider each one for failure.
if (!info.laggy()) {
return age.count();
}
+ bool is_mon_down() const {
+ int max = monmap->size();
+ int actual = get_quorum().size();
+ auto now = ceph::real_clock::now();
+ return actual < max && now > monmap->created.to_real_time();
+ }
+
// -- elector --
private:
std::unique_ptr<Paxos> paxos;