mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Discovery: do not allow passing negative cluster size
When an etcd instance attempts to perform service discovery, if a cluster size with negative value is provided, the etcd instance will panic without recovery because of
This commit is contained in:
parent
cdc1c8f02f
commit
a3e242c085
@ -211,7 +211,7 @@ func (d *discovery) createSelf(contents string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) {
|
func (d *discovery) checkCluster() ([]*client.Node, uint64, uint64, error) {
|
||||||
configKey := path.Join("/", d.cluster, "_config")
|
configKey := path.Join("/", d.cluster, "_config")
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
|
||||||
// find cluster size
|
// find cluster size
|
||||||
@ -230,7 +230,7 @@ func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) {
|
|||||||
}
|
}
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
size, err := strconv.Atoi(resp.Node.Value)
|
size, err := strconv.ParseUint(resp.Node.Value, 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, ErrBadSizeKey
|
return nil, 0, 0, ErrBadSizeKey
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) {
|
|||||||
if path.Base(nodes[i].Key) == path.Base(d.selfKey()) {
|
if path.Base(nodes[i].Key) == path.Base(d.selfKey()) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if i >= size-1 {
|
if uint64(i) >= size-1 {
|
||||||
return nodes[:size], size, resp.Index, ErrFullCluster
|
return nodes[:size], size, resp.Index, ErrFullCluster
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ func (d *discovery) logAndBackoffForRetry(step string) {
|
|||||||
d.clock.Sleep(retryTimeInSecond)
|
d.clock.Sleep(retryTimeInSecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *discovery) checkClusterRetry() ([]*client.Node, int, uint64, error) {
|
func (d *discovery) checkClusterRetry() ([]*client.Node, uint64, uint64, error) {
|
||||||
if d.retries < nRetries {
|
if d.retries < nRetries {
|
||||||
d.logAndBackoffForRetry("cluster status check")
|
d.logAndBackoffForRetry("cluster status check")
|
||||||
return d.checkCluster()
|
return d.checkCluster()
|
||||||
@ -300,8 +300,8 @@ func (d *discovery) waitNodesRetry() ([]*client.Node, error) {
|
|||||||
return nil, ErrTooManyRetries
|
return nil, ErrTooManyRetries
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *discovery) waitNodes(nodes []*client.Node, size int, index uint64) ([]*client.Node, error) {
|
func (d *discovery) waitNodes(nodes []*client.Node, size uint64, index uint64) ([]*client.Node, error) {
|
||||||
if len(nodes) > size {
|
if uint64(len(nodes)) > size {
|
||||||
nodes = nodes[:size]
|
nodes = nodes[:size]
|
||||||
}
|
}
|
||||||
// watch from the next index
|
// watch from the next index
|
||||||
@ -317,8 +317,8 @@ func (d *discovery) waitNodes(nodes []*client.Node, size int, index uint64) ([]*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wait for others
|
// wait for others
|
||||||
for len(all) < size {
|
for uint64(len(all)) < size {
|
||||||
plog.Noticef("found %d peer(s), waiting for %d more", len(all), size-len(all))
|
plog.Noticef("found %d peer(s), waiting for %d more", len(all), int(size-uint64(len(all))))
|
||||||
resp, err := w.Next(context.Background())
|
resp, err := w.Next(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ce, ok := err.(*client.ClusterError); ok {
|
if ce, ok := err.(*client.ClusterError); ok {
|
||||||
@ -338,7 +338,7 @@ func (d *discovery) selfKey() string {
|
|||||||
return path.Join("/", d.cluster, d.id.String())
|
return path.Join("/", d.cluster, d.id.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodesToCluster(ns []*client.Node, size int) (string, error) {
|
func nodesToCluster(ns []*client.Node, size uint64) (string, error) {
|
||||||
s := make([]string, len(ns))
|
s := make([]string, len(ns))
|
||||||
for i, n := range ns {
|
for i, n := range ns {
|
||||||
s[i] = n.Value
|
s[i] = n.Value
|
||||||
@ -348,7 +348,7 @@ func nodesToCluster(ns []*client.Node, size int) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return us, ErrInvalidURL
|
return us, ErrInvalidURL
|
||||||
}
|
}
|
||||||
if m.Len() != size {
|
if uint64(m.Len()) != size {
|
||||||
return us, ErrDuplicateName
|
return us, ErrDuplicateName
|
||||||
}
|
}
|
||||||
return us, nil
|
return us, nil
|
||||||
|
@ -215,7 +215,7 @@ func TestCheckCluster(t *testing.T) {
|
|||||||
if reflect.DeepEqual(ns, tt.nodes) {
|
if reflect.DeepEqual(ns, tt.nodes) {
|
||||||
t.Errorf("#%d: nodes = %v, want %v", i, ns, tt.nodes)
|
t.Errorf("#%d: nodes = %v, want %v", i, ns, tt.nodes)
|
||||||
}
|
}
|
||||||
if size != tt.wsize {
|
if size != uint64(tt.wsize) {
|
||||||
t.Errorf("#%d: size = %v, want %d", i, size, tt.wsize)
|
t.Errorf("#%d: size = %v, want %d", i, size, tt.wsize)
|
||||||
}
|
}
|
||||||
if index != tt.index {
|
if index != tt.index {
|
||||||
@ -299,7 +299,7 @@ func TestWaitNodes(t *testing.T) {
|
|||||||
fc.Advance(time.Second * (0x1 << i))
|
fc.Advance(time.Second * (0x1 << i))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
g, err := d.waitNodes(tt.nodes, 3, 0) // we do not care about index in this test
|
g, err := d.waitNodes(tt.nodes, uint64(3), 0) // we do not care about index in this test
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("#%d: err = %v, want %v", i, err, nil)
|
t.Errorf("#%d: err = %v, want %v", i, err, nil)
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ func TestCreateSelf(t *testing.T) {
|
|||||||
func TestNodesToCluster(t *testing.T) {
|
func TestNodesToCluster(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
nodes []*client.Node
|
nodes []*client.Node
|
||||||
size int
|
size uint64
|
||||||
wcluster string
|
wcluster string
|
||||||
werr error
|
werr error
|
||||||
}{
|
}{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user