Skip to content

Commit d9dc281

Browse files
committed
fix: delete sockets on shim exit
Signed-off-by: Henry Wang <[email protected]>
1 parent bfdc224 commit d9dc281

File tree

4 files changed

+81
-3
lines changed

4 files changed

+81
-3
lines changed

integration/client/container_linux_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/containerd/containerd/v2/core/containers"
4040
"github.com/containerd/containerd/v2/pkg/cio"
4141
"github.com/containerd/containerd/v2/pkg/oci"
42+
"github.com/containerd/containerd/v2/pkg/shim"
4243
"github.com/containerd/containerd/v2/pkg/sys"
4344
"github.com/containerd/containerd/v2/plugins"
4445
"github.com/containerd/errdefs"
@@ -312,6 +313,67 @@ func TestShimDoesNotLeakPipes(t *testing.T) {
312313
}
313314
}
314315

316+
func TestShimDoesNotLeakSockets(t *testing.T) {
317+
client, err := newClient(t, address)
318+
if err != nil {
319+
t.Fatal(err)
320+
}
321+
defer client.Close()
322+
323+
var (
324+
image Image
325+
ctx, cancel = testContext(t)
326+
id = t.Name()
327+
)
328+
defer cancel()
329+
330+
image, err = client.GetImage(ctx, testImage)
331+
if err != nil {
332+
t.Fatal(err)
333+
}
334+
335+
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "30")))
336+
if err != nil {
337+
t.Fatal(err)
338+
}
339+
340+
task, err := container.NewTask(ctx, empty())
341+
if err != nil {
342+
t.Fatal(err)
343+
}
344+
345+
exitChannel, err := task.Wait(ctx)
346+
if err != nil {
347+
t.Fatal(err)
348+
}
349+
350+
if err := task.Start(ctx); err != nil {
351+
t.Fatal(err)
352+
}
353+
354+
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
355+
t.Fatal(err)
356+
}
357+
358+
<-exitChannel
359+
360+
if _, err := task.Delete(ctx); err != nil {
361+
t.Fatal(err)
362+
}
363+
364+
if err := container.Delete(ctx, WithSnapshotCleanup); err != nil {
365+
t.Fatal(err)
366+
}
367+
368+
s, err := shim.SocketAddress(ctx, address, id)
369+
if err != nil {
370+
t.Fatal(err)
371+
}
372+
if _, err = os.Stat(strings.TrimPrefix(s, "unix://")); err == nil || !os.IsNotExist(err) {
373+
t.Errorf("Shim sockets have leaked after container has been deleted.")
374+
}
375+
}
376+
315377
func numPipes(pid int) (int, error) {
316378
cmd := exec.Command("sh", "-c", fmt.Sprintf("lsof -p %d | grep FIFO", pid))
317379

pkg/shim/shim.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,14 @@ func run(ctx context.Context, manager Manager, config Config) error {
411411

412412
if err := serve(ctx, server, signals, sd.Shutdown); err != nil {
413413
if !errors.Is(err, shutdown.ErrShutdown) {
414+
cleanupSockets(ctx)
414415
return err
415416
}
416417
}
417418

418419
// NOTE: If the shim server is down(like oom killer), the address
419420
// socket might be leaking.
420-
if address, err := ReadAddress("address"); err == nil {
421-
_ = RemoveSocket(address)
422-
}
421+
cleanupSockets(ctx)
423422

424423
select {
425424
case <-sd.Done():

pkg/shim/util_unix.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,14 @@ func dialHybridVsock(address string, timeout time.Duration) (net.Conn, error) {
279279
}
280280
return hybridVsockDialer(addr, port, timeout)
281281
}
282+
283+
func cleanupSockets(ctx context.Context) {
284+
if address, err := ReadAddress("address"); err == nil {
285+
_ = RemoveSocket(address)
286+
}
287+
if len(socketFlag) > 0 {
288+
_ = RemoveSocket("unix://" + socketFlag)
289+
} else if address, err := SocketAddress(ctx, addressFlag, id); err == nil {
290+
_ = RemoveSocket(address)
291+
}
292+
}

pkg/shim/util_windows.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,9 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
8585
func RemoveSocket(address string) error {
8686
return nil
8787
}
88+
89+
func cleanupSockets(context.Context) {
90+
if address, err := ReadAddress("address"); err == nil {
91+
_ = RemoveSocket(address)
92+
}
93+
}

0 commit comments

Comments
 (0)