From d5c69190d162c1cfb7c268acf2abe667dc206ad3 Mon Sep 17 00:00:00 2001 From: Flavio Crisciani Date: Tue, 30 May 2017 16:26:27 -0700 Subject: [PATCH] Fix leak of watchMiss goroutine The netlink socket that was used to monitor the L2 miss was never being closed. The watchMiss goroutine spawned was never returning. This was causing goroutine leak in case of createNetwork/destroyNetwork Signed-off-by: Flavio Crisciani --- libnetwork/drivers/overlay/ov_network.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libnetwork/drivers/overlay/ov_network.go b/libnetwork/drivers/overlay/ov_network.go index f24390ec7c..6be88d9179 100644 --- a/libnetwork/drivers/overlay/ov_network.go +++ b/libnetwork/drivers/overlay/ov_network.go @@ -58,6 +58,7 @@ type network struct { dbIndex uint64 dbExists bool sbox osl.Sandbox + nlSocket *nl.NetlinkSocket endpoints endpointTable driver *driver joinCnt int @@ -345,6 +346,12 @@ func (n *network) destroySandbox() { } } + // Close the netlink socket, this will also release the watchMiss goroutine that is using it + if n.nlSocket != nil { + n.nlSocket.Close() + n.nlSocket = nil + } + n.sbox.Destroy() n.sbox = nil } @@ -685,6 +692,7 @@ func (n *network) initSandbox(restore bool) error { sbox.InvokeFunc(func() { nlSock, err = nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH) }) + n.setNetlinkSocket(nlSock) if err == nil { go n.watchMiss(nlSock) @@ -700,6 +708,13 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket) { for { msgs, err := nlSock.Receive() if err != nil { + n.Lock() + nlFd := nlSock.GetFd() + n.Unlock() + if nlFd == -1 { + // The netlink socket got closed, simply exit to not leak this goroutine + return + } logrus.Errorf("Failed to receive from netlink: %v ", err) continue } @@ -816,6 +831,12 @@ func (n *network) setSandbox(sbox osl.Sandbox) { n.Unlock() } +func (n *network) setNetlinkSocket(nlSk *nl.NetlinkSocket) { + n.Lock() + n.nlSocket = nlSk + n.Unlock() +} + func (n *network) vxlanID(s *subnet) uint32 { n.Lock() defer n.Unlock()