ldout(cct, 10) << __func__ << " from " << from << " mepoch: "
<< mepoch << " epoch: " << epoch << dendl;
ldout(cct, 30) << "last_election_winner: " << last_election_winner << dendl;
+ // ignore proposal from marked down mons if we are the tiebreaker
+ if (elector->is_tiebreaker(elector->get_my_rank()) &&
+ elector->is_stretch_marked_down_mons(from)) {
+ ldout(cct, 10) << "Ignoring proposal from marked down mon " << from << dendl;
+ return;
+ }
if ((epoch % 2 == 0) &&
last_election_winner != elector->get_my_rank() &&
!elector->is_current_member(from)) {
* @returns true if we have participated, false otherwise
*/
virtual bool ever_participated() const = 0;
+ /**
+ * Check if the monitor is the tiebreaker in a stretch cluster.
+ *
+ * @returns true if the Monitor is the tiebreaker, false otherwise.
+ */
+ virtual bool is_tiebreaker(int rank) const = 0;
+ /**
+ * Check if the Monitor is marked down in a stretch cluster.
+ *
+ * @returns true if the Monitor in a stretch cluster is marked down, false otherwise.
+ */
+ virtual bool is_stretch_marked_down_mons(int rank) const = 0;
/**
* Ask the ElectionOwner for the size of the Paxos set. This includes
* those monitors which may not be in the current quorum!
return peer_tracker.is_clean(mon->rank, paxos_size());
}
+bool Elector::is_tiebreaker(int rank) const
+{
+ return mon->monmap->tiebreaker_mon == mon->monmap->get_name(rank);
+}
+
+bool Elector::is_stretch_marked_down_mons(int rank) const
+{
+ std::string mon_name = mon->monmap->get_name(rank);
+ for (auto& i : mon->monmap->stretch_marked_down_mons) {
+ if (i == mon_name) {
+ return true;
+ }
+ }
+ return false;
+}
+
void Elector::notify_clear_peer_state()
{
dout(10) << __func__ << dendl;
/* Right now we don't disallow anybody */
std::set<int> disallowed_leaders;
const std::set<int>& get_disallowed_leaders() const { return disallowed_leaders; }
+ /**
+ * Check if the monitor is the tiebreaker in a stretch cluster.
+ *
+ * @returns true if the Monitor is the tiebreaker, false otherwise.
+ */
+ bool is_tiebreaker(int rank) const;
+ /**
+ * Check if the mon is marked dwon in stretch mode.
+ *
+ * @returns true if the monitor is marked down in stretch mode,
+ * otherwise return false.
+ */
+ bool is_stretch_marked_down_mons(int from) const;
/**
* Reset the expire_event timer so we can limit the amount of time we
* will be electing. Clean up our peer_info.
std::set<std::string> disallowed_leaders; // can't be leader under CONNECTIVITY/DISALLOW
bool stretch_mode_enabled = false;
std::string tiebreaker_mon;
- std::set<std::string> stretch_marked_down_mons; // can't be leader until fully recovered
+ std::set<std::string> stretch_marked_down_mons; // can't be leader or taken proposal in CONNECTIVITY
+ // seriously until fully recovered
public:
void calc_legacy_ranks();
bool timer_election; // the timeout is for normal election, or victory
bool rank_deleted = false;
string prefix_str;
+ set<int> stretch_marked_down_mons;
+ int tiebreaker_mon_rank;
Owner(int r, ElectionLogic::election_strategy es, double tracker_halflife,
Election *p) : parent(p), rank(r), persisted_epoch(0),
ever_joined(false),
quorum = members;
victory_accepters = 1;
}
+ bool is_stretch_marked_down_mons(int rank) const {
+ for (auto& i : stretch_marked_down_mons) {
+ if (i == rank) {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool is_tiebreaker(int rank) const
+ {
+ return tiebreaker_mon_rank == rank;
+ }
bool is_current_member(int r) const { return quorum.count(r) != 0; }
void receive_propose(int from, epoch_t e, ConnectionTracker *oct) {
if (rank_deleted) return;