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 <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2024-10-29 10:42:03 +01:00
parent 3a7e1deed4
commit 1f44d0f8b2

View File

@ -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