Merge pull request #10193 from henry118/shim-sock

fix: delete sockets on shim exit
This commit is contained in:
Maksym Pavlenko 2024-05-09 05:06:41 +00:00 committed by GitHub
commit b168147ca8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 81 additions and 3 deletions

View File

@ -39,6 +39,7 @@ import (
"github.com/containerd/containerd/v2/core/containers" "github.com/containerd/containerd/v2/core/containers"
"github.com/containerd/containerd/v2/pkg/cio" "github.com/containerd/containerd/v2/pkg/cio"
"github.com/containerd/containerd/v2/pkg/oci" "github.com/containerd/containerd/v2/pkg/oci"
"github.com/containerd/containerd/v2/pkg/shim"
"github.com/containerd/containerd/v2/pkg/sys" "github.com/containerd/containerd/v2/pkg/sys"
"github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/plugins"
"github.com/containerd/errdefs" "github.com/containerd/errdefs"
@ -312,6 +313,67 @@ func TestShimDoesNotLeakPipes(t *testing.T) {
} }
} }
func TestShimDoesNotLeakSockets(t *testing.T) {
client, err := newClient(t, address)
if err != nil {
t.Fatal(err)
}
defer client.Close()
var (
image Image
ctx, cancel = testContext(t)
id = t.Name()
)
defer cancel()
image, err = client.GetImage(ctx, testImage)
if err != nil {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "30")))
if err != nil {
t.Fatal(err)
}
task, err := container.NewTask(ctx, empty())
if err != nil {
t.Fatal(err)
}
exitChannel, err := task.Wait(ctx)
if err != nil {
t.Fatal(err)
}
if err := task.Start(ctx); err != nil {
t.Fatal(err)
}
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
t.Fatal(err)
}
<-exitChannel
if _, err := task.Delete(ctx); err != nil {
t.Fatal(err)
}
if err := container.Delete(ctx, WithSnapshotCleanup); err != nil {
t.Fatal(err)
}
s, err := shim.SocketAddress(ctx, address, id)
if err != nil {
t.Fatal(err)
}
if _, err = os.Stat(strings.TrimPrefix(s, "unix://")); err == nil || !os.IsNotExist(err) {
t.Errorf("Shim sockets have leaked after container has been deleted.")
}
}
func numPipes(pid int) (int, error) { func numPipes(pid int) (int, error) {
cmd := exec.Command("sh", "-c", fmt.Sprintf("lsof -p %d | grep FIFO", pid)) cmd := exec.Command("sh", "-c", fmt.Sprintf("lsof -p %d | grep FIFO", pid))

View File

@ -411,15 +411,14 @@ func run(ctx context.Context, manager Manager, config Config) error {
if err := serve(ctx, server, signals, sd.Shutdown); err != nil { if err := serve(ctx, server, signals, sd.Shutdown); err != nil {
if !errors.Is(err, shutdown.ErrShutdown) { if !errors.Is(err, shutdown.ErrShutdown) {
cleanupSockets(ctx)
return err return err
} }
} }
// NOTE: If the shim server is down(like oom killer), the address // NOTE: If the shim server is down(like oom killer), the address
// socket might be leaking. // socket might be leaking.
if address, err := ReadAddress("address"); err == nil { cleanupSockets(ctx)
_ = RemoveSocket(address)
}
select { select {
case <-sd.Done(): case <-sd.Done():

View File

@ -279,3 +279,14 @@ func dialHybridVsock(address string, timeout time.Duration) (net.Conn, error) {
} }
return hybridVsockDialer(addr, port, timeout) return hybridVsockDialer(addr, port, timeout)
} }
func cleanupSockets(ctx context.Context) {
if address, err := ReadAddress("address"); err == nil {
_ = RemoveSocket(address)
}
if len(socketFlag) > 0 {
_ = RemoveSocket("unix://" + socketFlag)
} else if address, err := SocketAddress(ctx, addressFlag, id); err == nil {
_ = RemoveSocket(address)
}
}

View File

@ -85,3 +85,9 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
func RemoveSocket(address string) error { func RemoveSocket(address string) error {
return nil return nil
} }
func cleanupSockets(context.Context) {
if address, err := ReadAddress("address"); err == nil {
_ = RemoveSocket(address)
}
}