spiegel_podman/pkg/specgen/generate/validate_linux.go
seonghun lee 655b8cee14 Hide --cpu-rt-period/--cpu-rt-runtime and mark them as NOP
Podman 6 dropped cgroups v1 support, and the kernel real-time
scheduler cgroup settings only exist on cgroups v1. That means the
--cpu-rt-period and --cpu-rt-runtime options can never take effect
anymore: on cgroups v2 the values only produce a warning and are
discarded.

As agreed in the linked issue, the full removal of the options is
deferred to the next major release (7.0) to avoid a breaking change
for anyone still setting them. For 6.x this commit implements the
agreed interim step:

- remove the option documentation (docs/source/markdown/options/
  cpu-rt-period.md and cpu-rt-runtime.md) and drop the @@option
  references from the podman-create, podman-run, podman-update and
  podman-container-clone man pages
- hide both flags from --help output
- change the existing warning to state that the option is a NOP,
  that the value is ignored, and that the option will be removed in
  the next major release

The e2e tests are updated to match the new warning text. Actual
removal of the flags and the spec fields is left for Podman 7.0.

Part of #29750

Signed-off-by: seonghun lee <harrisleesh@gmail.com>
2026-09-17 01:15:52 +09:00

67 lines
2.4 KiB
Go

//go:build !remote
package generate
import (
"os"
"path/filepath"
"go.podman.io/common/pkg/cgroups"
"go.podman.io/podman/v6/pkg/specgen"
"go.podman.io/storage/pkg/fileutils"
)
// Verify resource limits are sanely set, removing any limits that are not
// possible with the current cgroups config.
func verifyContainerResources(s *specgen.SpecGenerator) ([]string, error) {
warnings := []string{}
if s.ResourceLimits == nil {
return warnings, nil
}
// Memory checks
if s.ResourceLimits.Memory != nil && s.ResourceLimits.Memory.Swap != nil {
own, err := cgroups.GetOwnCgroup()
if err != nil {
return warnings, err
}
if own == "/" {
// If running under the root cgroup try to create or reuse a "probe" cgroup to read memory values
own = "podman_probe"
_ = os.MkdirAll(filepath.Join("/sys/fs/cgroup", own), 0o755)
_ = os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644)
}
memoryMax := filepath.Join("/sys/fs/cgroup", own, "memory.max")
memorySwapMax := filepath.Join("/sys/fs/cgroup", own, "memory.swap.max")
errMemoryMax := fileutils.Exists(memoryMax)
errMemorySwapMax := fileutils.Exists(memorySwapMax)
// Differently than cgroup v1, the memory.*max files are not present in the
// root directory, so we cannot query directly that, so as best effort use
// the current cgroup.
// Check whether memory.max exists in the current cgroup and memory.swap.max
// does not. In this case we can be sure memory swap is not enabled.
// If both files don't exist, the memory controller might not be enabled
// for the current cgroup.
if errMemoryMax == nil && errMemorySwapMax != nil {
warnings = append(warnings, "Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.")
s.ResourceLimits.Memory.Swap = nil
}
}
// CPU checks
if s.ResourceLimits.CPU != nil {
cpu := s.ResourceLimits.CPU
if cpu.RealtimePeriod != nil {
warnings = append(warnings, "Realtime period is not supported as it requires cgroups v1, the value is ignored (NOP) and the option will be removed in the next major release")
cpu.RealtimePeriod = nil
}
if cpu.RealtimeRuntime != nil {
warnings = append(warnings, "Realtime runtime is not supported as it requires cgroups v1, the value is ignored (NOP) and the option will be removed in the next major release")
cpu.RealtimeRuntime = nil
}
}
return warnings, nil
}