mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdserver: fix a node panic bug caused LeaseTimeToLive call on a nonexistent lease
When the non Leader etcd server receives a LeaseTimeToLive on a nonexistent lease, it responds with a nil resp and a nil error The invoking function parses the nil resp and results a segmentation fault. I fix the bug by making sure the lease not found error is returned so that the invoking function parses the the error message instead. fix #6537
This commit is contained in:
parent
e68cd086ee
commit
8ef6687018
@ -308,17 +308,15 @@ func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var lresp *pb.LeaseTimeToLiveResponse
|
|
||||||
for _, url := range leader.PeerURLs {
|
for _, url := range leader.PeerURLs {
|
||||||
lurl := url + leasehttp.LeaseInternalPrefix
|
lurl := url + leasehttp.LeaseInternalPrefix
|
||||||
var iresp *leasepb.LeaseInternalResponse
|
var iresp *leasepb.LeaseInternalResponse
|
||||||
iresp, err = leasehttp.TimeToLiveHTTP(ctx, lease.LeaseID(r.ID), r.Keys, lurl, s.peerRt)
|
iresp, err = leasehttp.TimeToLiveHTTP(ctx, lease.LeaseID(r.ID), r.Keys, lurl, s.peerRt)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
lresp = iresp.LeaseTimeToLiveResponse
|
return iresp.LeaseTimeToLiveResponse, nil
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lresp, nil
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *EtcdServer) waitLeader() (*membership.Member, error) {
|
func (s *EtcdServer) waitLeader() (*membership.Member, error) {
|
||||||
|
@ -243,7 +243,31 @@ func TestV3PutOnNonExistLease(t *testing.T) {
|
|||||||
putr := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar"), Lease: badLeaseID}
|
putr := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar"), Lease: badLeaseID}
|
||||||
_, err := toGRPC(clus.RandClient()).KV.Put(ctx, putr)
|
_, err := toGRPC(clus.RandClient()).KV.Put(ctx, putr)
|
||||||
if !eqErrGRPC(err, rpctypes.ErrGRPCLeaseNotFound) {
|
if !eqErrGRPC(err, rpctypes.ErrGRPCLeaseNotFound) {
|
||||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCCompacted)
|
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCLeaseNotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestV3GetNonExistLease tests the case where the non exist lease is report as lease not found error using LeaseTimeToLive()
|
||||||
|
// A bug was found when a non leader etcd server returns nil instead of lease not found error which caues the server to crash.
|
||||||
|
// related issue https://github.com/coreos/etcd/issues/6537
|
||||||
|
func TestV3GetNonExistLease(t *testing.T) {
|
||||||
|
defer testutil.AfterTest(t)
|
||||||
|
clus := NewClusterV3(t, &ClusterConfig{Size: 3})
|
||||||
|
defer clus.Terminate(t)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
leaseTTLr := &pb.LeaseTimeToLiveRequest{
|
||||||
|
ID: 123,
|
||||||
|
Keys: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, client := range clus.clients {
|
||||||
|
_, err := toGRPC(client).Lease.LeaseTimeToLive(ctx, leaseTTLr)
|
||||||
|
if !eqErrGRPC(err, rpctypes.ErrGRPCLeaseNotFound) {
|
||||||
|
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCLeaseNotFound)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user