]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: fix standby-replay assignment logic
authorSage Weil <sage@newdream.net>
Tue, 26 Apr 2011 21:43:24 +0000 (14:43 -0700)
committerSage Weil <sage@newdream.net>
Tue, 26 Apr 2011 21:43:24 +0000 (14:43 -0700)
Assign a standby-replay at any time based on rank, name, or no preference.
Previously this could only happen when the MDS first started, and we would
fail if the target MDS wasn't followable at that point in time.

Signed-off-by: Sage Weil <sage@newdream.net>
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h

index 41f94887c87b0195174c7c13bf1ba7ddb51c7475..4a299eed16c4175604b4aee1e3fca4a6983f2cd2 100644 (file)
@@ -1046,8 +1046,7 @@ void MDSMonitor::tick()
         ++j) {
       MDSMap::mds_info_t& info = j->second;
       
-      if (info.state != MDSMap::STATE_STANDBY ||
-         info.standby_for_rank != MDSMap::MDS_STANDBY_ANY)
+      if (info.state != MDSMap::STATE_STANDBY)
        continue;
 
       /*
@@ -1056,28 +1055,28 @@ void MDSMonitor::tick()
        */
       dout(20) << "gid " << j->first << " is standby and following nobody" << dendl;
       
-      uint64_t lgid = 0;
+      // standby for someone specific?
+      if (info.standby_for_rank >= 0) {
+       if (pending_mdsmap.is_followable(info.standby_for_rank) &&
+           try_standby_replay(info, pending_mdsmap.mds_info[pending_mdsmap.up[info.standby_for_rank]]))
+         do_propose = true;
+       continue;
+      }
+
+      // check everyone
       for (map<uint64_t,MDSMap::mds_info_t>::iterator i = pending_mdsmap.mds_info.begin();
           i != pending_mdsmap.mds_info.end();
           ++i) {
        if (i->second.rank >= 0 && pending_mdsmap.is_followable(i->second.rank)) {
-         if ((lgid = pending_mdsmap.find_standby_for(i->second.rank, i->second.name))) {
-           MDSMap::mds_info_t& sinfo = i->second;
-           dout(20) << " mds" << i->second.rank
-                    << " standby gid " << lgid << " has state "
-                    << ceph_mds_state_name(sinfo.state)
-                    << dendl;
-           if (sinfo.state == MDSMap::STATE_STANDBY_REPLAY) {
-             dout(20) << "  skipping this MDS since it has a follower!" << dendl;
-             continue; // this MDS already has a standby
-           }
+         if (info.standby_for_name.length() &&
+             info.standby_for_name != i->second.name)
+           continue;   // we're supposed to follow someone else
+
+         if (try_standby_replay(info, i->second)) {
+           do_propose = true;
+           break;
          }
-         // hey, we found an MDS without a standby. Pair them!
-         info.standby_for_rank = i->second.rank;
-         dout(10) << "  setting to shadow mds rank " << info.standby_for_rank << dendl;
-         info.state = MDSMap::STATE_STANDBY_REPLAY;
-         do_propose = true;
-         break;
+         continue;
        }
       }
     }
@@ -1087,6 +1086,29 @@ void MDSMonitor::tick()
     propose_pending();
 }
 
+bool MDSMonitor::try_standby_replay(MDSMap::mds_info_t& finfo, MDSMap::mds_info_t& ainfo)
+{
+  // someone else already following?
+  uint64_t lgid = pending_mdsmap.find_standby_for(ainfo.rank, ainfo.name);
+  if (lgid) {
+    MDSMap::mds_info_t& sinfo = pending_mdsmap.mds_info[lgid];
+    dout(20) << " mds" << ainfo.rank
+            << " standby gid " << lgid << " with state "
+            << ceph_mds_state_name(sinfo.state)
+            << dendl;
+    if (sinfo.state == MDSMap::STATE_STANDBY_REPLAY) {
+      dout(20) << "  skipping this MDS since it has a follower!" << dendl;
+      return false; // this MDS already has a standby
+    }
+  }
+
+  // hey, we found an MDS without a standby. Pair them!
+  finfo.standby_for_rank = ainfo.rank;
+  dout(10) << "  setting to shadow mds rank " << finfo.standby_for_rank << dendl;
+  finfo.state = MDSMap::STATE_STANDBY_REPLAY;
+  return true;
+}
+
 
 void MDSMonitor::do_stop()
 {
index 0f0b2e88581ee05a0a2be4aca172695d44e88bc4..e976122ee197e741943de08aa1b15bba9c7ecf11 100644 (file)
@@ -100,6 +100,8 @@ class MDSMonitor : public PaxosService {
   };
   map<uint64_t, beacon_info_t> last_beacon;
 
+  bool try_standby_replay(MDSMap::mds_info_t& finfo, MDSMap::mds_info_t& ainfo);
+
 public:
   MDSMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p) { }