diff --git a/src/runtime/virtcontainers/api.go b/src/runtime/virtcontainers/api.go index 6cda1db3db..0bd1d650b9 100644 --- a/src/runtime/virtcontainers/api.go +++ b/src/runtime/virtcontainers/api.go @@ -141,6 +141,18 @@ func CleanupContainer(ctx context.Context, sandboxID, containerID string, force } defer s.Release(ctx) + // If the hypervisor process is already gone -- e.g. the sandbox was torn + // down by the main shim and this is containerd invoking the `delete` + // binary (cleanupAfterDeadShim) for a `docker run --rm` -- any agent RPC + // below would block on a dead vsock connection until the caller times out + // and SIGKILLs us, which surfaces as a failed container removal. Mark the + // agent dead so those calls fail fast; the force path then only performs + // host-side cleanup. + if !IsHypervisorRunning(s.hypervisor) { + s.Logger().Info("hypervisor is not running, marking agent dead before cleanup") + s.agent.markDead(ctx) + } + _, err = s.StopContainer(ctx, containerID, force) if err != nil && !force { return err diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 4aa2812df3..71b932deef 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -18,6 +18,7 @@ import ( "runtime" "strconv" "strings" + "syscall" "github.com/pkg/errors" @@ -1252,6 +1253,20 @@ func GetHypervisorPid(h Hypervisor) int { return pids[0] } +// IsHypervisorRunning reports whether the hypervisor process backing the +// sandbox is still alive. It is best-effort: a missing pidfile or a pid that +// no longer maps to a live process is treated as "not running". +func IsHypervisorRunning(h Hypervisor) bool { + pid := GetHypervisorPid(h) + if pid <= 0 { + return false + } + // Signal 0 performs error checking without sending a signal: nil means + // the process exists, EPERM means it exists but we may not signal it. + err := syscall.Kill(pid, 0) + return err == nil || err == syscall.EPERM +} + // Kind of guest protection type guestProtection uint8