From: 胡玮文 Date: Sun, 9 Jan 2022 14:52:16 +0000 (+0800) Subject: mds/FSMap: stricter state_transition_valid X-Git-Tag: v17.2.4~52^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=af3fe0a0a96ce3f497eb27cb47d795c9f45c4932;p=ceph.git mds/FSMap: stricter state_transition_valid Reject any unknown transitions. MDSRank::state initialize to standy and assert no update is missed. Signed-off-by: 胡玮文 (cherry picked from commit 0601552b91a1c91314bc6799514f972098b02f30) --- diff --git a/src/mds/MDSMap.cc b/src/mds/MDSMap.cc index 3a417b02ab9b..b54ad444d3b4 100644 --- a/src/mds/MDSMap.cc +++ b/src/mds/MDSMap.cc @@ -999,28 +999,44 @@ MDSMap::availability_t MDSMap::is_cluster_available() const bool MDSMap::state_transition_valid(DaemonState prev, DaemonState next) { - bool state_valid = true; - if (next != prev) { - if (prev == MDSMap::STATE_REPLAY) { - if (next != MDSMap::STATE_RESOLVE && next != MDSMap::STATE_RECONNECT) { - state_valid = false; - } - } else if (prev == MDSMap::STATE_REJOIN) { - if (next != MDSMap::STATE_ACTIVE && - next != MDSMap::STATE_CLIENTREPLAY && - next != MDSMap::STATE_STOPPED) { - state_valid = false; - } - } else if (prev >= MDSMap::STATE_RESOLVE && prev < MDSMap::STATE_ACTIVE) { - // Once I have entered replay, the only allowable transitions are to - // the next next along in the sequence. - if (next != prev + 1) { - state_valid = false; - } + if (next == prev) + return true; + if (next == MDSMap::STATE_DAMAGED) + return true; + + if (prev == MDSMap::STATE_BOOT) { + return next == MDSMap::STATE_STANDBY; + } else if (prev == MDSMap::STATE_STANDBY) { + return next == MDSMap::STATE_STANDBY_REPLAY || + next == MDSMap::STATE_REPLAY || + next == MDSMap::STATE_CREATING || + next == MDSMap::STATE_STARTING; + } else if (prev == MDSMap::STATE_CREATING || prev == MDSMap::STATE_STARTING) { + return next == MDSMap::STATE_ACTIVE; + } else if (prev == MDSMap::STATE_STANDBY_REPLAY) { + return next == MDSMap::STATE_REPLAY; + } else if (prev == MDSMap::STATE_REPLAY) { + return next == MDSMap::STATE_RESOLVE || + next == MDSMap::STATE_RECONNECT; + } else if (prev >= MDSMap::STATE_RESOLVE && prev < MDSMap::STATE_ACTIVE) { + // Once I have entered replay, the only allowable transitions are to + // the next next along in the sequence. + // Except... + if (prev == MDSMap::STATE_REJOIN && + (next == MDSMap::STATE_ACTIVE || // No need to do client replay + next == MDSMap::STATE_STOPPED)) { // no subtrees + return true; } + return next == prev + 1; + } else if (prev == MDSMap::STATE_ACTIVE) { + return next == MDSMap::STATE_STOPPING; + } else if (prev == MDSMap::STATE_STOPPING) { + return next == MDSMap::STATE_STOPPED; + } else { + derr << __func__ << ": Unknown prev state " + << ceph_mds_state_name(prev) << "(" << prev << ")" << dendl; + return false; } - - return state_valid; } bool MDSMap::check_health(mds_rank_t standby_daemon_count) diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 980ecd51eba2..014ee06317ae 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -2238,8 +2238,15 @@ void MDSRankDispatcher::handle_mds_map( // I am only to be passed MDSMaps in which I hold a rank ceph_assert(whoami != MDS_RANK_NONE); - MDSMap::DaemonState oldstate = state; mds_gid_t mds_gid = mds_gid_t(monc->get_global_id()); + MDSMap::DaemonState oldstate = oldmap.get_state_gid(mds_gid); + if (oldstate == MDSMap::STATE_NULL) { + // monitor may skip sending me the STANDBY map (e.g. if paxos_propose_interval is high) + // Assuming I have passed STANDBY state if I got a rank in the first map. + oldstate = MDSMap::STATE_STANDBY; + } + // I should not miss map update + ceph_assert(state == oldstate); state = mdsmap->get_state_gid(mds_gid); if (state != oldstate) { last_state = oldstate; diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index c0897071048f..d0e01f229578 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -413,7 +413,7 @@ class MDSRank { // The last different state I held before current MDSMap::DaemonState last_state = MDSMap::STATE_BOOT; // The state assigned to me by the MDSMap - MDSMap::DaemonState state = MDSMap::STATE_BOOT; + MDSMap::DaemonState state = MDSMap::STATE_STANDBY; bool cluster_degraded = false;