From 1f44d0f8b2b12d1d67d3474b160310d121af91d6 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 29 Oct 2024 10:42:03 +0100 Subject: [PATCH] libpod: report cgroups deleted during Stat() call The cgroup.Stat() operation is not atomic, so it's possible that the cgroup is removed during the Stat() call. Catch specific errors that can occur when the cgroup is missing and validate the existence of the cgroup path. If the cgroup is not found, return a more specific error indicating that the container has been removed. Closes: https://github.com/containers/podman/issues/23789 Signed-off-by: Giuseppe Scrivano --- libpod/stats_linux.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libpod/stats_linux.go b/libpod/stats_linux.go index 36f861aa3e..c2f53fc16f 100644 --- a/libpod/stats_linux.go +++ b/libpod/stats_linux.go @@ -3,6 +3,7 @@ package libpod import ( + "errors" "fmt" "strings" "syscall" @@ -36,6 +37,11 @@ func (c *Container) getPlatformContainerStats(stats *define.ContainerStats, prev // Ubuntu does not have swap memory in cgroups because swap is often not enabled. cgroupStats, err := cgroup.Stat() if err != nil { + // cgroup.Stat() is not an atomic operation, so it is possible that the cgroup is removed + // while Stat() is running. Try to catch this case and return a more specific error. + if (errors.Is(err, unix.ENOENT) || errors.Is(err, unix.ENODEV)) && !cgroupExist(cgroupPath) { + return fmt.Errorf("cgroup %s does not exist: %w", cgroupPath, define.ErrCtrStopped) + } return fmt.Errorf("unable to obtain cgroup stats: %w", err) } conState := c.state.State