Selaa lähdekoodia

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 <flavio.crisciani@docker.com>
Flavio Crisciani 8 vuotta sitten
vanhempi
commit
d5c69190d1
1 muutettua tiedostoa jossa 21 lisäystä ja 0 poistoa
  1. 21 0
      libnetwork/drivers/overlay/ov_network.go

+ 21 - 0
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()