From 3dcc65353322edc9a9f53c6f6a11092859920c6b Mon Sep 17 00:00:00 2001 From: Laura Brehm Date: Tue, 11 Jun 2024 18:01:56 +0100 Subject: [PATCH] plugins: cleanup sockets when done Since 509123f935e6fcb2cedf0df7bd8585a346082969, we've been leaking sockets in the filesystem on platforms where abstract sockets aren't supported. That change relied on Go to cleanup our sockets for us, which Go will happily do as long as we make sure to close the listener, which we weren't previously doing unless to signal the plugin to terminate. This change adds a deferred call to `PluginServer.Close()`, which makes sure we close the plugin server at the end of the plugin execution, so that we never exit without cleaning up. Signed-off-by: Laura Brehm --- cli-plugins/socket/socket.go | 8 ++++++++ cmd/docker/docker.go | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/cli-plugins/socket/socket.go b/cli-plugins/socket/socket.go index fc91e78d8f..7096b42b2e 100644 --- a/cli-plugins/socket/socket.go +++ b/cli-plugins/socket/socket.go @@ -9,6 +9,8 @@ import ( "os" "runtime" "sync" + + "github.com/sirupsen/logrus" ) // EnvKey represents the well-known environment variable used to pass the @@ -30,6 +32,7 @@ func NewPluginServer(h func(net.Conn)) (*PluginServer, error) { if err != nil { return nil, err } + logrus.Trace("Plugin server listening on ", l.Addr()) if h == nil { h = func(net.Conn) {} @@ -92,6 +95,7 @@ func (pl *PluginServer) Addr() net.Addr { // // The error value is that of the underlying [net.Listner.Close] call. func (pl *PluginServer) Close() error { + logrus.Trace("Closing plugin server") // Close connections first to ensure the connections get io.EOF instead // of a connection reset. pl.closeAllConns() @@ -107,6 +111,10 @@ func (pl *PluginServer) closeAllConns() { pl.mu.Lock() defer pl.mu.Unlock() + if pl.closed { + return + } + // Prevent new connections from being accepted. pl.closed = true diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go index f5dad2ec79..3cf0ba966f 100644 --- a/cmd/docker/docker.go +++ b/cmd/docker/docker.go @@ -245,6 +245,11 @@ func tryPluginRun(ctx context.Context, dockerCli command.Cli, cmd *cobra.Command if err == nil { plugincmd.Env = append(plugincmd.Env, socket.EnvKey+"="+srv.Addr().String()) } + defer func() { + // Close the server when plugin execution is over, so that in case + // it's still open, any sockets on the filesystem are cleaned up. + _ = srv.Close() + }() // Set additional environment variables specified by the caller. plugincmd.Env = append(plugincmd.Env, envs...)