From: Sage Weil Date: Tue, 26 Apr 2011 21:43:24 +0000 (-0700) Subject: mon: fix standby-replay assignment logic X-Git-Tag: v0.28~139^2~20 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=53a8e7d6de20ba6e11a23d7458701af5c8457304;p=ceph.git mon: fix standby-replay assignment logic 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 --- diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index 41f94887c87b..4a299eed16c4 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -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::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() { diff --git a/src/mon/MDSMonitor.h b/src/mon/MDSMonitor.h index 0f0b2e88581e..e976122ee197 100644 --- a/src/mon/MDSMonitor.h +++ b/src/mon/MDSMonitor.h @@ -100,6 +100,8 @@ class MDSMonitor : public PaxosService { }; map 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) { }