dhcp: don't try to close the lease stop channel multiple times
Fixes: https://github.com/containernetworking/plugins/issues/105
This commit is contained in:
@ -251,4 +251,69 @@ var _ = Describe("DHCP Operations", func() {
|
|||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("correctly handles multiple DELs for the same container", func() {
|
||||||
|
conf := `{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"name": "mynet",
|
||||||
|
"type": "ipvlan",
|
||||||
|
"ipam": {
|
||||||
|
"type": "dhcp"
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "dummy",
|
||||||
|
Netns: targetNS.Path(),
|
||||||
|
IfName: contVethName,
|
||||||
|
StdinData: []byte(conf),
|
||||||
|
}
|
||||||
|
|
||||||
|
var addResult *current.Result
|
||||||
|
err := originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
r, _, err := testutils.CmdAddWithResult(targetNS.Path(), contVethName, []byte(conf), func() error {
|
||||||
|
return cmdAdd(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
addResult, err = current.GetResult(r)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(len(addResult.IPs)).To(Equal(1))
|
||||||
|
Expect(addResult.IPs[0].Address.String()).To(Equal("192.168.1.5/24"))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
wg.Add(3)
|
||||||
|
started := sync.WaitGroup{}
|
||||||
|
started.Add(3)
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
go func() {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
// Wait until all goroutines are running
|
||||||
|
started.Done()
|
||||||
|
started.Wait()
|
||||||
|
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
return testutils.CmdDelWithResult(targetNS.Path(), contVethName, func() error {
|
||||||
|
return cmdDel(args)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
return testutils.CmdDelWithResult(targetNS.Path(), contVethName, func() error {
|
||||||
|
return cmdDel(args)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d2g/dhcp4"
|
"github.com/d2g/dhcp4"
|
||||||
@ -55,6 +56,7 @@ type DHCPLease struct {
|
|||||||
renewalTime time.Time
|
renewalTime time.Time
|
||||||
rebindingTime time.Time
|
rebindingTime time.Time
|
||||||
expireTime time.Time
|
expireTime time.Time
|
||||||
|
stopping uint32
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
@ -106,7 +108,9 @@ func AcquireLease(clientID, netns, ifName string) (*DHCPLease, error) {
|
|||||||
// Stop terminates the background task that maintains the lease
|
// Stop terminates the background task that maintains the lease
|
||||||
// and issues a DHCP Release
|
// and issues a DHCP Release
|
||||||
func (l *DHCPLease) Stop() {
|
func (l *DHCPLease) Stop() {
|
||||||
close(l.stop)
|
if atomic.CompareAndSwapUint32(&l.stopping, 0, 1) {
|
||||||
|
close(l.stop)
|
||||||
|
}
|
||||||
l.wg.Wait()
|
l.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user