1
0
mirror of https://github.com/containers/podman.git synced 2026-02-05 06:45:31 +01:00

libpod/container_internal*.go: Remove Cgroups v1

Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
This commit is contained in:
Lokesh Mandvekar
2025-11-05 09:14:07 -05:00
parent f2c9fcd68f
commit 4d404f1f1d
2 changed files with 25 additions and 114 deletions

View File

@@ -41,7 +41,6 @@ import (
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
"go.podman.io/common/libnetwork/etchosts"
"go.podman.io/common/pkg/cgroups"
"go.podman.io/common/pkg/chown"
"go.podman.io/common/pkg/config"
"go.podman.io/common/pkg/hooks"
@@ -1361,41 +1360,25 @@ func (c *Container) waitForHealthy(ctx context.Context) error {
}
// Whether a container should use `all` when stopping
func (c *Container) stopWithAll() (bool, error) {
func (c *Container) stopWithAll() bool {
// If the container is running in a PID Namespace, then killing the
// primary pid is enough to kill the container. If it is not running in
// a pid namespace then the OCI Runtime needs to kill ALL processes in
// the container's cgroup in order to make sure the container is stopped.
all := !c.hasNamespace(spec.PIDNamespace)
// We can't use --all if Cgroups aren't present.
// Rootless containers with Cgroups v1 and NoCgroups are both cases
// where this can happen.
if all {
if c.config.NoCgroups {
all = false
} else if rootless.IsRootless() {
// Only do this check if we need to
unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return false, err
}
if !unified {
all = false
}
}
// Rootless containers with NoCgroups is a case where this can happen.
if all && c.config.NoCgroups {
all = false
}
return all, nil
return all
}
// Internal, non-locking function to stop container
func (c *Container) stop(timeout uint) error {
logrus.Debugf("Stopping ctr %s (timeout %d)", c.ID(), timeout)
all, err := c.stopWithAll()
if err != nil {
return err
}
all := c.stopWithAll()
// OK, the following code looks a bit weird but we have to make sure we can stop
// containers with the restart policy always, to do this we have to set
@@ -1502,7 +1485,7 @@ func (c *Container) waitForConmonToExitAndSave() error {
// could open a pidfd on container PID1 before
// this to get the real exit code... But I'm not
// that dedicated.
all, _ := c.stopWithAll()
all := c.stopWithAll()
if err := c.ociRuntime.StopContainer(c, 0, all); err != nil {
logrus.Errorf("Error stopping container %s after Conmon exited prematurely: %v", c.ID(), err)
}
@@ -1559,16 +1542,6 @@ func (c *Container) pause() error {
return fmt.Errorf("cannot pause without using Cgroups: %w", define.ErrNoCgroups)
}
if rootless.IsRootless() {
cgroupv2, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return fmt.Errorf("failed to determine cgroupversion: %w", err)
}
if !cgroupv2 {
return fmt.Errorf("can not pause containers on rootless containers with cgroup V1: %w", define.ErrNoCgroups)
}
}
if c.state.HCUnitName != "" {
if err := c.removeTransientFiles(context.Background(),
c.config.StartupHealthCheckConfig != nil && !c.state.StartupHCPassed,

View File

@@ -3,7 +3,6 @@
package libpod
import (
"errors"
"fmt"
"io/fs"
"os"
@@ -222,7 +221,7 @@ func (c *Container) reloadNetwork() error {
// systemd expects to have /run, /run/lock and /tmp on tmpfs
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) error {
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) {
var containerUUIDSet bool
for _, s := range c.config.Spec.Process.Env {
if strings.HasPrefix(s, "container_uuid=") {
@@ -265,11 +264,6 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
g.AddMount(tmpfsMnt)
}
unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return err
}
hasCgroupNs := false
for _, ns := range c.config.Spec.Linux.Namespaces {
if ns.Type == spec.CgroupNamespace {
@@ -278,71 +272,25 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
}
}
if unified {
g.RemoveMount("/sys/fs/cgroup")
g.RemoveMount("/sys/fs/cgroup")
var systemdMnt spec.Mount
if hasCgroupNs {
systemdMnt = spec.Mount{
Destination: "/sys/fs/cgroup",
Type: "cgroup",
Source: "cgroup",
Options: []string{"private", "rw"},
}
} else {
systemdMnt = spec.Mount{
Destination: "/sys/fs/cgroup",
Type: define.TypeBind,
Source: "/sys/fs/cgroup",
Options: []string{define.TypeBind, "private", "rw"},
}
var systemdMnt spec.Mount
if hasCgroupNs {
systemdMnt = spec.Mount{
Destination: "/sys/fs/cgroup",
Type: "cgroup",
Source: "cgroup",
Options: []string{"private", "rw"},
}
g.AddMount(systemdMnt)
} else {
hasSystemdMount := MountExists(mounts, "/sys/fs/cgroup/systemd")
if hasCgroupNs && !hasSystemdMount {
return errors.New("cgroup namespace is not supported with cgroup v1 and systemd mode")
}
mountOptions := []string{define.TypeBind, "rprivate"}
if !hasSystemdMount {
skipMount := hasSystemdMount
var statfs unix.Statfs_t
if err := unix.Statfs("/sys/fs/cgroup/systemd", &statfs); err != nil {
if errors.Is(err, os.ErrNotExist) {
// If the mount is missing on the host, we cannot bind mount it so
// just skip it.
skipMount = true
}
mountOptions = append(mountOptions, "nodev", "noexec", "nosuid")
} else {
if statfs.Flags&unix.MS_NODEV == unix.MS_NODEV {
mountOptions = append(mountOptions, "nodev")
}
if statfs.Flags&unix.MS_NOEXEC == unix.MS_NOEXEC {
mountOptions = append(mountOptions, "noexec")
}
if statfs.Flags&unix.MS_NOSUID == unix.MS_NOSUID {
mountOptions = append(mountOptions, "nosuid")
}
if statfs.Flags&unix.MS_RDONLY == unix.MS_RDONLY {
mountOptions = append(mountOptions, "ro")
}
}
if !skipMount {
systemdMnt := spec.Mount{
Destination: "/sys/fs/cgroup/systemd",
Type: define.TypeBind,
Source: "/sys/fs/cgroup/systemd",
Options: mountOptions,
}
g.AddMount(systemdMnt)
g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
}
systemdMnt = spec.Mount{
Destination: "/sys/fs/cgroup",
Type: define.TypeBind,
Source: "/sys/fs/cgroup",
Options: []string{define.TypeBind, "private", "rw"},
}
}
return nil
g.AddMount(systemdMnt)
}
// Add an existing container's namespace to the spec
@@ -383,16 +331,12 @@ func isRootlessCgroupSet(cgroup string) bool {
}
func (c *Container) expectPodCgroup() (bool, error) {
unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return false, err
}
cgroupManager := c.CgroupManager()
switch {
case c.config.NoCgroups:
return false, nil
case cgroupManager == config.SystemdCgroupsManager:
return !rootless.IsRootless() || unified, nil
return true, nil
case cgroupManager == config.CgroupfsCgroupsManager:
return !rootless.IsRootless(), nil
default:
@@ -402,10 +346,6 @@ func (c *Container) expectPodCgroup() (bool, error) {
// Get cgroup path in a format suitable for the OCI spec
func (c *Container) getOCICgroupPath() (string, error) {
unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return "", err
}
cgroupManager := c.CgroupManager()
switch {
case c.config.NoCgroups:
@@ -423,7 +363,7 @@ func (c *Container) getOCICgroupPath() (string, error) {
systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
logrus.Debugf("Setting Cgroups for container %s to %s", c.ID(), systemdCgroups)
return systemdCgroups, nil
case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)):
case (rootless.IsRootless() && cgroupManager == config.CgroupfsCgroupsManager):
if c.config.CgroupParent == "" || !isRootlessCgroupSet(c.config.CgroupParent) {
return "", nil
}
@@ -458,9 +398,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
func (c *Container) addSystemdMounts(g *generate.Generator) error {
if c.Systemd() {
if err := c.setupSystemd(g.Mounts(), *g); err != nil {
return err
}
c.setupSystemd(g.Mounts(), *g)
}
return nil
}