sandbox: tolerate a shim exiting during ShutdownSandbox

A sandbox shim may exit as soon as it has shut its sandbox down, before
containerd reads the ShutdownSandbox response, in which case the client
sees ttrpc.ErrClosed. The task Shutdown RPC has the same race and
shimTask.Shutdown treats a closed connection as a successful shutdown;
controllerLocal.Shutdown returned it as an error instead, failing
RemovePodSandbox for a sandbox that was already gone.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
This commit is contained in:
Maksym Pavlenko committed 2026-11-04 18:25:47 -08:00
1 parent da144993d5
commit d113e117d8
1 file changed
+6 -1
+6 -1
View File
@@ -18,6 +18,7 @@ package sandbox
import (
"context"
"errors"
"fmt"
"os"
"time"
@@ -27,6 +28,7 @@ import (
"github.com/containerd/log"
"github.com/containerd/plugin"
"github.com/containerd/plugin/registry"
"github.com/containerd/ttrpc"
"github.com/containerd/typeurl/v2"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -260,8 +262,11 @@ func (c *controllerLocal) Shutdown(ctx context.Context, sandboxID string) error
return err
}
// A shim may exit as soon as it has shut its sandbox down, before the
// response is read; a closed connection means the shutdown happened, as
// for the task Shutdown RPC.
_, err = svc.ShutdownSandbox(ctx, &runtimeAPI.ShutdownSandboxRequest{SandboxID: sandboxID})
if err != nil {
if err != nil && !errors.Is(err, ttrpc.ErrClosed) {
return fmt.Errorf("failed to shutdown sandbox: %w", errgrpc.ToNative(err))
}