From 83fc54c1b75bf9eb6a3f731e49ad721cc32a9a52 Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Mon, 4 Feb 2019 21:46:59 +0100
Subject: [PATCH] Fix #3217: upgrade leads to protocol version (2) is
incompatible: [1, 0]
This is fixed in https://github.com/hashicorp/memberlist/pull/178, bump
memberlist to fix possible split brain in Consul.
---
.../hashicorp/memberlist/memberlist.go | 21 ++++++++-------
.../github.com/hashicorp/memberlist/state.go | 26 +++++++++++++++++--
vendor/vendor.json | 2 +-
3 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/vendor/github.com/hashicorp/memberlist/memberlist.go b/vendor/github.com/hashicorp/memberlist/memberlist.go
index bd8abd23f858..7be42f1e9333 100644
--- a/vendor/github.com/hashicorp/memberlist/memberlist.go
+++ b/vendor/github.com/hashicorp/memberlist/memberlist.go
@@ -72,6 +72,15 @@ type Memberlist struct {
logger *log.Logger
}
+// BuildVsnArray creates the array of Vsn
+func (conf *Config) BuildVsnArray() []uint8 {
+ return []uint8{
+ ProtocolVersionMin, ProtocolVersionMax, conf.ProtocolVersion,
+ conf.DelegateProtocolMin, conf.DelegateProtocolMax,
+ conf.DelegateProtocolVersion,
+ }
+}
+
// newMemberlist creates the network listeners.
// Does not schedule execution of background maintenance.
func newMemberlist(conf *Config) (*Memberlist, error) {
@@ -402,11 +411,7 @@ func (m *Memberlist) setAlive() error {
Addr: addr,
Port: uint16(port),
Meta: meta,
- Vsn: []uint8{
- ProtocolVersionMin, ProtocolVersionMax, m.config.ProtocolVersion,
- m.config.DelegateProtocolMin, m.config.DelegateProtocolMax,
- m.config.DelegateProtocolVersion,
- },
+ Vsn: m.config.BuildVsnArray(),
}
m.aliveNode(&a, nil, true)
return nil
@@ -447,11 +452,7 @@ func (m *Memberlist) UpdateNode(timeout time.Duration) error {
Addr: state.Addr,
Port: state.Port,
Meta: meta,
- Vsn: []uint8{
- ProtocolVersionMin, ProtocolVersionMax, m.config.ProtocolVersion,
- m.config.DelegateProtocolMin, m.config.DelegateProtocolMax,
- m.config.DelegateProtocolVersion,
- },
+ Vsn: m.config.BuildVsnArray(),
}
notifyCh := make(chan struct{})
m.aliveNode(&a, notifyCh, true)
diff --git a/vendor/github.com/hashicorp/memberlist/state.go b/vendor/github.com/hashicorp/memberlist/state.go
index f51692de0ac7..bbcd11eab0c9 100644
--- a/vendor/github.com/hashicorp/memberlist/state.go
+++ b/vendor/github.com/hashicorp/memberlist/state.go
@@ -841,11 +841,26 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) {
return
}
+ if len(a.Vsn) >= 3 {
+ pMin := a.Vsn[0]
+ pMax := a.Vsn[1]
+ pCur := a.Vsn[2]
+ if pMin == 0 || pMax == 0 || pMin > pMax {
+ m.logger.Printf("[WARN] memberlist: Ignoring an alive message for '%s' (%v:%d) because protocol version(s) are wrong: %d <= %d <= %d should be >0", a.Node, net.IP(a.Addr), a.Port, pMin, pCur, pMax)
+ return
+ }
+ }
+
// Invoke the Alive delegate if any. This can be used to filter out
// alive messages based on custom logic. For example, using a cluster name.
// Using a merge delegate is not enough, as it is possible for passive
// cluster merging to still occur.
if m.config.Alive != nil {
+ if len(a.Vsn) < 6 {
+ m.logger.Printf("[WARN] memberlist: ignoring alive message for '%s' (%v:%d) because Vsn is not present",
+ a.Node, net.IP(a.Addr), a.Port)
+ return
+ }
node := &Node{
Name: a.Node,
Addr: a.Addr,
@@ -877,6 +892,14 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) {
},
State: stateDead,
}
+ if len(a.Vsn) > 5 {
+ state.PMin = a.Vsn[0]
+ state.PMax = a.Vsn[1]
+ state.PCur = a.Vsn[2]
+ state.DMin = a.Vsn[3]
+ state.DMax = a.Vsn[4]
+ state.DCur = a.Vsn[5]
+ }
// Add to map
m.nodeMap[a.Node] = state
@@ -956,9 +979,8 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) {
bytes.Equal(a.Vsn, versions) {
return
}
-
m.refute(state, a.Incarnation)
- m.logger.Printf("[WARN] memberlist: Refuting an alive message")
+ m.logger.Printf("[WARN] memberlist: Refuting an alive message for '%s' (%v:%d) meta:(%v VS %v), vsn:(%v VS %v)", a.Node, net.IP(a.Addr), a.Port, a.Meta, state.Meta, a.Vsn, versions)
} else {
m.encodeBroadcastNotify(a.Node, aliveMsg, a, notify)
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 24e946448654..bd0d3372fc0d 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -145,7 +145,7 @@
{"path":"github.com/hashicorp/hil","checksumSHA1":"kqCMCHy2b+RBMKC+ER+OPqp8C3E=","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"},
{"path":"github.com/hashicorp/hil/ast","checksumSHA1":"UICubs001+Q4MsUf9zl2vcMzWQQ=","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"},
{"path":"github.com/hashicorp/logutils","checksumSHA1":"vt+P9D2yWDO3gdvdgCzwqunlhxU=","revision":"0dc08b1671f34c4250ce212759ebd880f743d883","revisionTime":"2015-06-09T07:04:31Z"},
- {"path":"github.com/hashicorp/memberlist","checksumSHA1":"q6yTL5vSGnWxUtcocVU3YIG/HNc=","revision":"b195c8e4fcc6284fff1583fd6ab09e68ca207551","revisionTime":"2018-08-09T14:04:54Z"},
+ {"path":"github.com/hashicorp/memberlist","checksumSHA1":"j4pWTjW3SFOPVwWBEZPuNHETnLE=","revision":"b38abf62d7f3ce5225722cd62a90cfb098e02519","revisionTime":"2019-02-04T18:04:39Z"},
{"path":"github.com/hashicorp/net-rpc-msgpackrpc","checksumSHA1":"qnlqWJYV81ENr61SZk9c65R1mDo=","revision":"a14192a58a694c123d8fe5481d4a4727d6ae82f3","revisionTime":"2015-11-16T02:03:38Z"},
{"path":"github.com/hashicorp/raft","checksumSHA1":"3U9bQLEMikE47n4TZP6uOdgXIyQ=","revision":"da92cfe76e0c1c9b94bbc9d884ec4b2b3b90b699","revisionTime":"2018-08-17T18:12:11Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/raft-boltdb","checksumSHA1":"QAxukkv54/iIvLfsUP6IK4R0m/A=","revision":"d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee","revisionTime":"2015-02-01T20:08:39Z"},