<< " " << ceph_mds_state_name(info.state)
<< " since " << beacon.stamp << dendl;
+ // We will only take decisive action (replacing/removing a daemon)
+ // if we have some indicating that some other daemon(s) are successfully
+ // getting beacons through recently.
+ utime_t latest_beacon;
+ for (const auto & i : last_beacon) {
+ latest_beacon = MAX(i.second.stamp, latest_beacon);
+ }
+ const bool may_replace = latest_beacon >
+ (ceph_clock_now() -
+ MAX(g_conf->mds_beacon_interval, g_conf->mds_beacon_grace * 0.5));
+
// are we in?
// and is there a non-laggy standby that can take over for us?
mds_gid_t sgid;
if (info.rank >= 0 &&
info.state != MDSMap::STATE_STANDBY &&
info.state != MDSMap::STATE_STANDBY_REPLAY &&
+ may_replace &&
!pending_fsmap.get_filesystem(fscid)->mds_map.test_flag(CEPH_MDSMAP_DOWN) &&
(sgid = pending_fsmap.find_replacement_for({fscid, info.rank}, info.name,
g_conf->mon_force_standby_active)) != MDS_GID_NONE)
pending_fsmap.promote(sgid, fs, info.rank);
*mds_propose = true;
- } else if (info.state == MDSMap::STATE_STANDBY_REPLAY ||
- info.state == MDSMap::STATE_STANDBY) {
+ } else if ((info.state == MDSMap::STATE_STANDBY_REPLAY ||
+ info.state == MDSMap::STATE_STANDBY) && may_replace) {
dout(10) << " failing and removing " << gid << " " << info.addr << " mds." << info.rank
<< "." << info.inc << " " << ceph_mds_state_name(info.state)
<< dendl;