I am not sure how we could receive a pre-vote reply for a term of the
actual vote, but if somehow it does happen, we must not accept it, as
the same server can vote differently in the pre-vote and the real vote
and so we may end up with more than one elected leader.
Ignore the pre-vote reply during the actual elections and warn the user
if this ever happens, so we could investigate further.
Found while investigating a report with a cluster with two elected
leaders. It may not be the cause of the issue and, as stated above,
I'm not even sure if receiving a pre-vote for the actual election term
is possible. But it's better to cover this case explicitly, as the
flag in the reply is not used today.
Fixes: 85634fd58004 ("ovsdb: raft: Support pre-vote mechanism to deal with
disruptive server.")
Signed-off-by: Ilya Maximets <[email protected]>
---
ovsdb/raft.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/ovsdb/raft.c b/ovsdb/raft.c
index 32349c8af..1fc8a5c34 100644
--- a/ovsdb/raft.c
+++ b/ovsdb/raft.c
@@ -1857,11 +1857,18 @@ raft_set_term(struct raft *raft, uint64_t term, const
struct uuid *vote)
static bool
raft_accept_vote(struct raft *raft, struct raft_server *s,
- const struct uuid *vote)
+ const struct uuid *vote, bool is_prevote)
{
if (uuid_equals(&s->vote, vote)) {
return false;
}
+ if (raft->prevote_passed && is_prevote) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_WARN_RL(&rl, "ignoring pre-vote reply from server %s "
+ "during the actual election on term %"PRIu64".",
+ s->nickname, raft->term);
+ return false;
+ }
if (!uuid_is_zero(&s->vote)) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
char buf1[SID_LEN + 1];
@@ -1959,7 +1966,7 @@ raft_start_election(struct raft *raft, bool is_prevote,
}
/* Vote for ourselves. */
- if (raft_accept_vote(raft, me, &raft->sid)) {
+ if (raft_accept_vote(raft, me, &raft->sid, is_prevote)) {
/* We just started vote, so it shouldn't be accepted yet unless this is
* a one-node cluster. In such case we don't do pre-vote, and become
* leader immediately. */
@@ -3985,7 +3992,7 @@ raft_handle_vote_reply(struct raft *raft,
struct raft_server *s = raft_find_peer(raft, &rpy->common.sid);
if (s) {
- if (raft_accept_vote(raft, s, &rpy->vote)) {
+ if (raft_accept_vote(raft, s, &rpy->vote, rpy->is_prevote)) {
if (raft->prevote_passed) {
raft_become_leader(raft);
} else {
--
2.52.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev