Skip to content

Commit d645d87

Browse files
authored
Merge pull request #4028 from norio-nomura/close-usernet-on-signal
`limactl usernet`: handle signal to close GVisorNetstack
2 parents 16ec1dd + 021f8a2 commit d645d87

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

cmd/limactl/usernet.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
"errors"
88
"fmt"
99
"os"
10+
"os/signal"
1011
"strconv"
12+
"syscall"
1113

1214
"github.com/spf13/cobra"
1315

@@ -77,10 +79,13 @@ func usernetAction(cmd *cobra.Command, _ []string) error {
7779
os.RemoveAll(qemuSocket)
7880
os.RemoveAll(fdSocket)
7981

82+
ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
83+
defer cancel()
84+
8085
// Environment Variables
8186
// LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT: Specifies the timeout duration for resolving IP addresses in minutes. Default is 2 minutes.
8287

83-
return usernet.StartGVisorNetstack(cmd.Context(), &usernet.GVisorNetstackOpts{
88+
return usernet.StartGVisorNetstack(ctx, &usernet.GVisorNetstackOpts{
8489
MTU: mtu,
8590
Endpoint: endpoint,
8691
QemuSocket: qemuSocket,

pkg/networks/usernet/gvproxy.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package usernet
66
import (
77
"bufio"
88
"context"
9+
"errors"
910
"fmt"
1011
"net"
1112
"net/http"
@@ -128,9 +129,16 @@ func listenQEMU(ctx context.Context, vn *virtualnetwork.VirtualNetwork) error {
128129

129130
go func() {
130131
defer listener.Close()
132+
<-ctx.Done()
133+
}()
134+
135+
go func() {
131136
for {
132137
conn, err := listener.Accept()
133138
if err != nil {
139+
if errors.Is(err, net.ErrClosed) {
140+
return
141+
}
134142
logrus.Error("QEMU accept failed", err)
135143
}
136144

@@ -162,10 +170,18 @@ func listenFD(ctx context.Context, vn *virtualnetwork.VirtualNetwork) error {
162170

163171
go func() {
164172
defer listener.Close()
173+
<-ctx.Done()
174+
}()
175+
176+
go func() {
165177
for {
166178
conn, err := listener.Accept()
167179
if err != nil {
180+
if errors.Is(err, net.ErrClosed) {
181+
return
182+
}
168183
logrus.Error("FD accept failed", err)
184+
continue // since conn is nil
169185
}
170186

171187
files, err := fd.Get(conn.(*net.UnixConn), 1, []string{"client"})
@@ -202,20 +218,20 @@ func listenFD(ctx context.Context, vn *virtualnetwork.VirtualNetwork) error {
202218
}
203219

204220
func httpServe(ctx context.Context, g *errgroup.Group, ln net.Listener, mux http.Handler) {
221+
s := &http.Server{
222+
Handler: mux,
223+
ReadTimeout: 10 * time.Second,
224+
WriteTimeout: 10 * time.Second,
225+
}
205226
g.Go(func() error {
206227
<-ctx.Done()
207-
return ln.Close()
228+
return s.Close()
208229
})
209230
g.Go(func() error {
210-
s := &http.Server{
211-
Handler: mux,
212-
ReadTimeout: 10 * time.Second,
213-
WriteTimeout: 10 * time.Second,
214-
}
215231
err := s.Serve(ln)
216232
if err != nil {
217-
if err != http.ErrServerClosed {
218-
return err
233+
if err == http.ErrServerClosed {
234+
return nil
219235
}
220236
return err
221237
}

pkg/networks/usernet/udpfileconn.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ type UDPFileConn struct {
1616
func (conn *UDPFileConn) Read(b []byte) (n int, err error) {
1717
// Check if the connection has been closed
1818
if err := conn.SetReadDeadline(time.Time{}); err != nil {
19-
var opErr *net.OpError
20-
if errors.As(err, &opErr) && opErr.Err.Error() == "use of closed network connection" {
19+
if errors.Is(err, net.ErrClosed) {
2120
return 0, errors.New("UDPFileConn connection closed")
2221
}
2322
}

0 commit comments

Comments
 (0)