From 76248a68b2668081640fe7c043dc1c58e21495f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20Lensb=C3=B8l?= Date: Thu, 7 May 2026 14:57:07 -0400 Subject: [PATCH] tstest/natlab/vnet: close gonet sockets when test is done (#19677) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running all vmtests in tstest/natlab/vmtest locally was breaking later tasks in the queue. The goroutine dump on timeout had goroutines hanging around for 9 minutes, meaning that something was not getting cleaned up. goroutine 262 [select, 9 minutes]: gvisor.dev/gvisor/pkg/tcpip/adapters/gonet.commonRead({...}) Add a timeout of Now() to gonet TCP connections when the test ends (inspired by ServeUnixConn()), and wait for them to shut down before exiting the test. Updates #13038 Signed-off-by: Claus Lensbøl --- tstest/natlab/vnet/vnet.go | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tstest/natlab/vnet/vnet.go b/tstest/natlab/vnet/vnet.go index 1c28c2c5d..c11e32843 100644 --- a/tstest/natlab/vnet/vnet.go +++ b/tstest/natlab/vnet/vnet.go @@ -205,7 +205,7 @@ func (n *network) initStack() error { return tcpFwd.HandlePacket(tei, pb) }) - go func() { + n.s.wg.Go(func() { for { pkt := n.linkEP.ReadContext(n.s.shutdownCtx) if pkt == nil { @@ -217,7 +217,7 @@ func (n *network) initStack() error { } n.handleIPPacketFromGvisor(pkt.ToView().AsSlice()) } - }() + }) return nil } @@ -369,8 +369,11 @@ func (n *network) acceptTCP(r *tcp.ForwarderRequest) { if destPort == 80 && fakeControl.Match(destIP) { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) hs := &http.Server{Handler: n.s.control} - go hs.Serve(netutil.NewOneConnListener(tc, nil)) + n.s.wg.Go(func() { + hs.Serve(netutil.NewOneConnListener(tc, nil)) + }) return } @@ -383,39 +386,54 @@ func (n *network) acceptTCP(r *tcp.ForwarderRequest) { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) tlsConn := tls.Server(tc, ds.tlsConfig) hs := &http.Server{Handler: ds.handler} - go hs.Serve(netutil.NewOneConnListener(tlsConn, nil)) + n.s.wg.Go(func() { + hs.Serve(netutil.NewOneConnListener(tlsConn, nil)) + }) return } if destPort == 80 { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) hs := &http.Server{Handler: n.s.derps[0].handler} - go hs.Serve(netutil.NewOneConnListener(tc, nil)) + n.s.wg.Go(func() { + hs.Serve(netutil.NewOneConnListener(tc, nil)) + }) return } } if destPort == 443 && fakeLogCatcher.Match(destIP) { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) - go n.serveLogCatcherConn(clientRemoteIP, tc) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) + n.s.wg.Go(func() { + n.serveLogCatcherConn(clientRemoteIP, tc) + }) return } if destPort == 80 && fakeCloudInit.Match(destIP) { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) hs := &http.Server{Handler: n.s.cloudInitHandler()} - go hs.Serve(netutil.NewOneConnListener(tc, nil)) + n.s.wg.Go(func() { + hs.Serve(netutil.NewOneConnListener(tc, nil)) + }) return } if destPort == 80 && fakeFiles.Match(destIP) { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) + context.AfterFunc(n.s.shutdownCtx, func() { tc.SetDeadline(time.Now()) }) hs := &http.Server{Handler: n.s.fileServerHandler()} - go hs.Serve(netutil.NewOneConnListener(tc, nil)) + n.s.wg.Go(func() { + hs.Serve(netutil.NewOneConnListener(tc, nil)) + }) return }