]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/FSMap: stricter state_transition_valid
author胡玮文 <huww98@outlook.com>
Sun, 9 Jan 2022 14:52:16 +0000 (22:52 +0800)
committerVenky Shankar <vshankar@redhat.com>
Thu, 1 Sep 2022 13:39:05 +0000 (19:09 +0530)
Reject any unknown transitions.

MDSRank::state initialize to standy and assert no update is missed.

Signed-off-by: 胡玮文 <huww98@outlook.com>
(cherry picked from commit 0601552b91a1c91314bc6799514f972098b02f30)

src/mds/MDSMap.cc
src/mds/MDSRank.cc
src/mds/MDSRank.h

index 3a417b02ab9b03bdc37ab88cc4f1a6cc39b74667..b54ad444d3b4636cbc192f8f292c2c1388ffe161 100644 (file)
@@ -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)
index 980ecd51eba2a79f00bd9a737bdb9f85c45a66a9..014ee06317aea70bdaedbf6a51bea699bc09915a 100644 (file)
@@ -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;
index c0897071048f5bc9db5bc2cfa54ee83a78708f49..d0e01f2295786cb32063b54d158ee333dde8f89d 100644 (file)
@@ -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;