diff options
-rw-r--r-- | cmd/podman/libpodruntime/runtime.go | 6 | ||||
-rw-r--r-- | cmd/podman/shared/create_cli.go | 7 | ||||
-rw-r--r-- | pkg/spec/spec.go | 10 | ||||
-rw-r--r-- | pkg/util/utils_supported.go | 24 | ||||
-rw-r--r-- | pkg/util/utils_windows.go | 5 |
5 files changed, 48 insertions, 4 deletions
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index b533dc056..b8d77602d 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -107,7 +107,11 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber bool, if c.Flags().Changed("cgroup-manager") { options = append(options, libpod.WithCgroupManager(c.GlobalFlags.CGroupManager)) } else { - if rootless.IsRootless() { + unified, err := util.IsCgroup2UnifiedMode() + if err != nil { + return nil, err + } + if rootless.IsRootless() && !unified { options = append(options, libpod.WithCgroupManager("cgroupfs")) } } diff --git a/cmd/podman/shared/create_cli.go b/cmd/podman/shared/create_cli.go index f731e8db5..7f158b09a 100644 --- a/cmd/podman/shared/create_cli.go +++ b/cmd/podman/shared/create_cli.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/cmd/podman/shared/parse" cc "github.com/containers/libpod/pkg/spec" "github.com/containers/libpod/pkg/sysinfo" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -76,6 +77,12 @@ func addWarning(warnings []string, msg string) []string { func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, error) { warnings := []string{} + + cgroup2, err := util.IsCgroup2UnifiedMode() + if err != nil || cgroup2 { + return warnings, err + } + sysInfo := sysinfo.New(true) // memory subsystem checks and adjustments diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 20c649f9a..c2c5e0900 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" pmount "github.com/containers/storage/pkg/mount" "github.com/docker/docker/oci/caps" "github.com/docker/go-units" @@ -347,10 +348,13 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM } if rootless.IsRootless() { - if addedResources { - return nil, errors.New("invalid configuration, cannot set resources with rootless containers") + cgroup2, err := util.IsCgroup2UnifiedMode() + if err != nil { + return nil, err + } + if addedResources && !cgroup2 { + return nil, errors.New("invalid configuration, cannot set resources with rootless containers not using cgroups v2 unified mode") } - configSpec.Linux.Resources = &spec.LinuxResources{} } // Make sure that the bind mounts keep options like nosuid, noexec, nodev. diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go index af5e67fc1..8b98658c2 100644 --- a/pkg/util/utils_supported.go +++ b/pkg/util/utils_supported.go @@ -11,9 +11,33 @@ import ( "github.com/pkg/errors" "os" "path/filepath" + "sync" "syscall" ) +const ( + _cgroup2SuperMagic = 0x63677270 +) + +var ( + isUnifiedOnce sync.Once + isUnified bool + isUnifiedErr error +) + +// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 unified mode. +func IsCgroup2UnifiedMode() (bool, error) { + isUnifiedOnce.Do(func() { + var st syscall.Statfs_t + if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil { + isUnified, isUnifiedErr = false, err + } else { + isUnified, isUnifiedErr = st.Type == _cgroup2SuperMagic, nil + } + }) + return isUnified, isUnifiedErr +} + // GetRootlessRuntimeDir returns the runtime directory when running as non root func GetRootlessRuntimeDir() (string, error) { var rootlessRuntimeDirError error diff --git a/pkg/util/utils_windows.go b/pkg/util/utils_windows.go index 1e9ccea90..b33733da9 100644 --- a/pkg/util/utils_windows.go +++ b/pkg/util/utils_windows.go @@ -10,3 +10,8 @@ import ( func GetRootlessRuntimeDir() (string, error) { return "", errors.New("this function is not implemented for windows") } + +// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 unified mode. +func IsCgroup2UnifiedMode() (bool, error) { + return false, errors.New("this function is not implemented for windows") +} |