From 495a35a6a6dea090cce0a85e6635204074617137 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Fri, 1 Apr 2016 09:04:14 +0100 Subject: [PATCH] work around fd re-use bug in vishvananda/netlink Closing a subscription can cause the associated fd to be re-used while the subscription goroutine is also still trying to use it. Which can have disastrous consequences. So as a work around we don't close subscriptions. This means we leak an fd, some buffer space, and goroutine. The latter will eventually block in a channel send of a subscription event, since nothing is left reading ont the other end. So at least it won't be consuming cycles. --- net/if.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/if.go b/net/if.go index f107433e..d4972cad 100644 --- a/net/if.go +++ b/net/if.go @@ -19,9 +19,10 @@ func EnsureInterface(ifaceName string) (*net.Interface, error) { func ensureInterface(ifaceName string) (*net.Interface, error) { ch := make(chan netlink.LinkUpdate) - done := make(chan struct{}) - defer close(done) - if err := netlink.LinkSubscribe(ch, done); err != nil { + // NB: We do not supply (and eventually close) a 'done' channel + // here since that can cause incorrect file descriptor + // re-usage. See https://github.com/weaveworks/weave/issues/2120 + if err := netlink.LinkSubscribe(ch, nil); err != nil { return nil, err } // check for currently-existing interface after subscribing, to avoid race @@ -46,9 +47,7 @@ func EnsureInterfaceAndMcastRoute(ifaceName string) (*net.Interface, error) { return nil, err } ch := make(chan netlink.RouteUpdate) - done := make(chan struct{}) - defer close(done) - if err := netlink.RouteSubscribe(ch, done); err != nil { + if err := netlink.RouteSubscribe(ch, nil); err != nil { return nil, err } dest := net.IPv4(224, 0, 0, 0)