From 8a4edae2c8551da56b05f09fcc39f774696c7e3a Mon Sep 17 00:00:00 2001 From: Tomasz Duda Date: Tue, 5 Nov 2024 19:39:31 +0100 Subject: [PATCH] support cgroup v1 mounted with noprefix --- libcontainer/cgroups/fs/cpuset.go | 71 +++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go index fe01ba98408..17650832818 100644 --- a/libcontainer/cgroups/fs/cpuset.go +++ b/libcontainer/cgroups/fs/cpuset.go @@ -1,11 +1,13 @@ package fs import ( + "bufio" "errors" "os" "path/filepath" "strconv" "strings" + "sync" "golang.org/x/sys/unix" @@ -14,6 +16,41 @@ import ( "github.com/opencontainers/runc/libcontainer/configs" ) +var ( + cpusetLock sync.Mutex + cpusetPrefix string + cpusetInit bool +) + +func getCpusetPrefix() string { + cpusetLock.Lock() + defer cpusetLock.Unlock() + + if cpusetInit { + return cpusetPrefix + } + + cpusetInit = true + cpusetPrefix = "cpuset." + + file, err := os.Open("/proc/self/mountinfo") + if err != nil { + return cpusetPrefix + } + defer file.Close() + + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, "cpuset") && strings.Contains(line, "cgroup") && strings.Contains(line, "noprefix") { + cpusetPrefix = "" + break + } + } + return cpusetPrefix +} + type CpusetGroup struct{} func (s *CpusetGroup) Name() string { @@ -26,12 +63,12 @@ func (s *CpusetGroup) Apply(path string, r *configs.Resources, pid int) error { func (s *CpusetGroup) Set(path string, r *configs.Resources) error { if r.CpusetCpus != "" { - if err := cgroups.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil { + if err := cgroups.WriteFile(path, getCpusetPrefix()+"cpus", r.CpusetCpus); err != nil { return err } } if r.CpusetMems != "" { - if err := cgroups.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil { + if err := cgroups.WriteFile(path, getCpusetPrefix()+"mems", r.CpusetMems); err != nil { return err } } @@ -83,57 +120,57 @@ func getCpusetStat(path string, file string) ([]uint16, error) { func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { var err error - stats.CPUSetStats.CPUs, err = getCpusetStat(path, "cpuset.cpus") + stats.CPUSetStats.CPUs, err = getCpusetStat(path, getCpusetPrefix()+"cpus") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.cpu_exclusive") + stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"cpu_exclusive") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.Mems, err = getCpusetStat(path, "cpuset.mems") + stats.CPUSetStats.Mems, err = getCpusetStat(path, getCpusetPrefix()+"mems") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_hardwall") + stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"mem_hardwall") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_exclusive") + stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"mem_exclusive") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_migrate") + stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"memory_migrate") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_page") + stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"memory_spread_page") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_slab") + stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"memory_spread_slab") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_pressure") + stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"memory_pressure") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, "cpuset.sched_load_balance") + stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, getCpusetPrefix()+"sched_load_balance") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } - stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, "cpuset.sched_relax_domain_level") + stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, getCpusetPrefix()+"sched_relax_domain_level") if err != nil && !errors.Is(err, os.ErrNotExist) { return err } @@ -172,10 +209,10 @@ func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error } func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) { - if cpus, err = cgroups.ReadFile(parent, "cpuset.cpus"); err != nil { + if cpus, err = cgroups.ReadFile(parent, getCpusetPrefix()+"cpus"); err != nil { return } - if mems, err = cgroups.ReadFile(parent, "cpuset.mems"); err != nil { + if mems, err = cgroups.ReadFile(parent, getCpusetPrefix()+"mems"); err != nil { return } return cpus, mems, nil @@ -221,12 +258,12 @@ func cpusetCopyIfNeeded(current, parent string) error { } if isEmptyCpuset(currentCpus) { - if err := cgroups.WriteFile(current, "cpuset.cpus", parentCpus); err != nil { + if err := cgroups.WriteFile(current, getCpusetPrefix()+"cpus", parentCpus); err != nil { return err } } if isEmptyCpuset(currentMems) { - if err := cgroups.WriteFile(current, "cpuset.mems", parentMems); err != nil { + if err := cgroups.WriteFile(current, getCpusetPrefix()+"mems", parentMems); err != nil { return err } }