timer(mds_lock),
name(n),
whoami(-1), incarnation(0),
+ standby_for_rank(MDSMap::MDS_NO_STANDBY_PREF),
standby_type(0),
continue_replay(false),
messenger(m),
standby_type = wanted_state;
}
+ standby_for_rank = g_conf.mds_standby_for_rank;
+ standby_for_name.assign(g_conf.mds_standby_for_name);
+
+ if (wanted_state == MDSMap::STATE_STANDBY_REPLAY &&
+ standby_for_rank == -1) {
+ if (standby_for_name.empty())
+ standby_for_rank = MDSMap::MDS_STANDBY_ANY;
+ else
+ standby_for_rank = MDSMap::MDS_STANDBY_NAME;
+ } else if (!standby_type && !standby_for_name.empty())
+ standby_for_rank = MDSMap::MDS_MATCHED_ACTIVE;
+
beacon_start();
whoami = -1;
messenger->set_myname(entity_name_t::MDS(whoami));
MMDSBeacon *beacon = new MMDSBeacon(monc->get_fsid(), monc->get_global_id(), name, mdsmap->get_epoch(),
want_state, beacon_last_seq);
- beacon->set_standby_for_rank(g_conf.mds_standby_for_rank);
- beacon->set_standby_for_name(g_conf.mds_standby_for_name);
+ beacon->set_standby_for_rank(standby_for_rank);
+ beacon->set_standby_for_name(standby_for_name);
// include _my_ feature set
beacon->set_compat(mdsmap_compat);
static const int STATE_ACTIVE = CEPH_MDS_STATE_ACTIVE; // up, active
static const int STATE_STOPPING = CEPH_MDS_STATE_STOPPING; // up, exporting metadata (-> standby or out)
+ // indicate startup standby preferences for MDS
+ // of course, if they have a specific rank to follow, they just set that!
+ static const int MDS_NO_STANDBY_PREF = -1; // doesn't have instructions to do anything
+ static const int MDS_STANDBY_ANY = -2; // is instructed to be standby-replay, may
+ // or may not have specific name to follow
+ static const int MDS_STANDBY_NAME = -3; // standby for a named MDS
+ static const int MDS_MATCHED_ACTIVE = -4; // has a matched standby, which if up
+ // it should follow, but otherwise should
+ // be assigned a rank
+
struct mds_info_t {
uint64_t global_id;
string name;
if (((p->second.rank == -1 &&
(p->second.standby_for_rank == mds ||
p->second.standby_for_name == name)) ||
- (p->second.standby_for_rank == -2)) &&
+ (p->second.standby_for_rank == MDS_STANDBY_ANY)) &&
(p->second.state == MDSMap::STATE_STANDBY ||
p->second.state == MDSMap::STATE_STANDBY_REPLAY) &&
!p->second.laggy()) {
- if (p->second.standby_for_rank == -2)
+ if (p->second.standby_for_rank == MDS_STANDBY_ANY)
generic_standby = p;
else
return p->first;
p != mds_info.end();
++p) {
if (p->second.rank == -1 &&
- p->second.standby_for_rank < 0 &&
+ (p->second.standby_for_rank == MDS_NO_STANDBY_PREF ||
+ p->second.standby_for_rank == MDS_MATCHED_ACTIVE) &&
p->second.state == MDSMap::STATE_STANDBY &&
!p->second.laggy()) {
return p->first;
(state == MDSMap::STATE_STANDBY_REPLAY ||
state == MDSMap::STATE_ONESHOT_REPLAY) &&
(pending_mdsmap.is_degraded() ||
- ((m->get_standby_for_rank() != -1) &&
+ ((m->get_standby_for_rank() >= 0) &&
pending_mdsmap.get_state(m->get_standby_for_rank()) < MDSMap::STATE_ACTIVE))) {
dout(10) << "mds_beacon can't standby-replay mds" << m->get_standby_for_rank() << " at this time (cluster degraded, or mds not active)" << dendl;
dout(10) << "pending_mdsmap.is_degraded()==" << pending_mdsmap.is_degraded()
info.standby_for_rank =
pending_mdsmap.find_by_name(info.standby_for_name)->rank;
}
- if (info.standby_for_rank >= 0) {
+ if (info.standby_for_rank >= 0 && !mdsmap.is_dne(info.standby_for_rank)) {
info.state = MDSMap::STATE_STANDBY_REPLAY;
}
pending_mdsmap.stopped.insert(info.rank);
pending_mdsmap.mds_info.erase(gid); // last! info is a ref into this map
last_beacon.erase(gid);
- } else if (state == MDSMap::STATE_STANDBY_REPLAY &&
- (m->get_standby_for_rank() == -1) &&
- (m->get_standby_for_name().empty())) {
- // note the MDS as available for standby_replay on any MDS
- dout(10) << "marking available for standby_replay" << dendl;
- info.standby_for_rank = -2;
- } else if (state == MDSMap::STATE_STANDBY_REPLAY &&
- m->get_standby_for_rank() == -1) {
- /* convert name to rank. If we don't have it, do nothing. The
+ } else if (state == MDSMap::STATE_STANDBY_REPLAY) {
+ if (m->get_standby_for_rank() == MDSMap::MDS_STANDBY_NAME) {
+ /* convert name to rank. If we don't have it, do nothing. The
mds will stay in standby and keep requesting the state change */
- dout(20) << "looking for mds " << m->get_standby_for_name()
- << " to STANDBY_REPLAY for" << dendl;
- if (pending_mdsmap.find_by_name(m->get_standby_for_name())) {
- info.standby_for_rank =
- pending_mdsmap.find_by_name(m->get_standby_for_name())->rank;
+ dout(20) << "looking for mds " << m->get_standby_for_name()
+ << " to STANDBY_REPLAY for" << dendl;
+ const MDSMap::mds_info_t *found_mds = NULL;
+ if ((found_mds = mdsmap.find_by_name(m->get_standby_for_name())) &&
+ (found_mds->rank >= 0)) {
+ info.standby_for_rank = found_mds->rank;
dout(10) <<" found mds " << m->get_standby_for_name()
- << "; it has rank " << info.standby_for_rank << dendl;
+ << "; it has rank " << info.standby_for_rank << dendl;
info.state = MDSMap::STATE_STANDBY_REPLAY;
info.state_seq = seq;
- }
+ }
+ } else if (m->get_standby_for_rank() >= 0 &&
+ !mdsmap.is_dne(m->get_standby_for_rank())) {
+ /* switch to standby-replay for this MDS*/
+ info.state = MDSMap::STATE_STANDBY_REPLAY;
+ info.state_seq = seq;
+ info.standby_for_rank = m->get_standby_for_rank();
+ } // else it's a standby for anybody, and is already in the list
} else {
info.state = state;
info.state_seq = seq;
continue;
}
- if (since >= cutoff && pending_mdsmap.mds_info[gid].standby_for_rank != -2)
+ if (since >= cutoff && pending_mdsmap.mds_info[gid].standby_for_rank != MDSMap::MDS_STANDBY_ANY)
continue;
MDSMap::mds_info_t& info = pending_mdsmap.mds_info[gid];
- if (since >= cutoff && info.standby_for_rank == -2) {
+ if (since >= cutoff && info.standby_for_rank == MDSMap::MDS_STANDBY_ANY) {
/* this mds is not laggy, but has no rank assigned.
* See if we can find it somebody to shadow
*/