On Tue, Dec 16, 2025 at 12:34 PM Ilya Maximets <[email protected]> wrote: > > 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.
Thanks Ilya. I can't think of how this could happen either, because a pre-vote reply for term T should already be rejected by raft_receive_term__() in raft_handle_vote_reply() since we're now at term T+1 for the real vote, but I agree with this patch as a defensive check. Probably it would be good to add a comment in the code to explain this is a defensive check for an unknown edge case. Acked-by: Han Zhou <[email protected]> > > 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
