standby_epochs[new_info.global_id] = epoch;
}
-void FSMap::stop(mds_gid_t who)
+std::list<mds_gid_t> FSMap::stop(mds_gid_t who)
{
assert(mds_roles.at(who) != FS_CLUSTER_ID_NONE);
auto fs = filesystems.at(mds_roles.at(who));
fs->mds_map.in.erase(info.rank);
fs->mds_map.stopped.insert(info.rank);
+ // Also drop any standby replays that were following this rank
+ std::list<mds_gid_t> standbys;
+ for (const auto &i : fs->mds_map.mds_info) {
+ const auto &other_gid = i.first;
+ const auto &other_info = i.second;
+ if (other_info.rank == info.rank
+ && other_info.state == MDSMap::STATE_STANDBY_REPLAY) {
+ standbys.push_back(other_gid);
+ erase(other_gid, 0);
+ }
+ }
+
fs->mds_map.mds_info.erase(who);
mds_roles.erase(who);
fs->mds_map.epoch = epoch;
+
+ return standbys;
}
/**
* A daemon reports that it is STATE_STOPPED: remove it,
* and the rank it held.
+ *
+ * @returns a list of any additional GIDs that were removed from the map
+ * as a side effect (like standby replays)
*/
- void stop(mds_gid_t who);
+ std::list<mds_gid_t> stop(mds_gid_t who);
/**
* The rank held by 'who', if any, is to be relinquished, and
<< " standby_for_rank=" << m->get_standby_for_rank()
<< dendl;
if (state == MDSMap::STATE_STOPPED) {
- pending_fsmap.stop(gid);
- last_beacon.erase(gid);
+ auto erased = pending_fsmap.stop(gid);
+ erased.push_back(gid);
+
+ for (const auto &erased_gid : erased) {
+ last_beacon.erase(erased_gid);
+ if (pending_daemon_health.count(erased_gid)) {
+ pending_daemon_health.erase(erased_gid);
+ pending_daemon_health_rm.insert(erased_gid);
+ }
+ }
} else if (state == MDSMap::STATE_DAMAGED) {
if (!mon->osdmon()->is_writeable()) {
dout(4) << __func__ << ": DAMAGED from rank " << info.rank