From ce3e9e68e867d579be812fae226ad4ea0ae1c5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20R=C3=B6der?= Date: Thu, 5 May 2022 10:58:54 +0200 Subject: [PATCH] util: support systems using the new cgroup v2 structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With cgroup v2, the location of the pids.max file changed and so did the /proc/self/cgroup file new /proc/self/cgroup file ` 0::/user.slice/user-500.slice/session-14.scope ` old file: ` 11:pids:/user.slice/user-500.slice/session-2.scope 10:blkio:/user.slice 9:net_cls,net_prio:/ 8:perf_event:/ ... ` There is no directory per subsystem (e.g. /sys/fs/cgroup/pids) any more, all files are now in one directory. fixes: https://github.com/ceph/ceph-csi/issues/3085 Signed-off-by: Marcus Röder --- internal/util/pidlimit.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/internal/util/pidlimit.go b/internal/util/pidlimit.go index 19271ba06659..0adfb9abb5eb 100644 --- a/internal/util/pidlimit.go +++ b/internal/util/pidlimit.go @@ -27,16 +27,19 @@ import ( ) const ( - procCgroup = "/proc/self/cgroup" - sysPidsMaxFmt = "/sys/fs/cgroup/pids%s/pids.max" + procCgroup = "/proc/self/cgroup" + sysPidsMaxFmtCgroupV1 = "/sys/fs/cgroup/pids%s/pids.max" + sysPidsMaxFmtCgroupV2 = "/sys/fs/cgroup%s/pids.max" ) -// return the cgouprs "pids.max" file of the current process -// -// find the line containing the pids group from the /proc/self/cgroup file -// $ grep 'pids' /proc/self/cgroup +// getCgroupPidsFile return the cgroups "pids.max" file of the +// current process +// For cgroup v1, find the line containing the pids group from the /proc/self/cgroup file +// $ grep ':pids:' /proc/self/cgroup // 7:pids:/kubepods.slice/kubepods-besteffort.slice/....scope // $ cat /sys/fs/cgroup/pids + *.scope + /pids.max. +// The entry for cgroup v2 is always in the format "0::...scope", no subsystem given. +// (see https://www.kernel.org/doc/Documentation/cgroup-v2.txt) func getCgroupPidsFile() (string, error) { cgroup, err := os.Open(procCgroup) if err != nil { @@ -44,6 +47,7 @@ func getCgroupPidsFile() (string, error) { } defer cgroup.Close() // #nosec: error on close is not critical here + pidsMax := "" scanner := bufio.NewScanner(cgroup) var slice string for scanner.Scan() { @@ -51,8 +55,16 @@ func getCgroupPidsFile() (string, error) { if parts == nil || len(parts) < 3 { continue } + // No cgroup subsystem given, then it is cgroupv2 + if parts[0] == "0" && parts[1] == "" { + slice = parts[2] + pidsMax = fmt.Sprintf(sysPidsMaxFmtCgroupV2, slice) + + break + } if parts[1] == "pids" { slice = parts[2] + pidsMax = fmt.Sprintf(sysPidsMaxFmtCgroupV1, slice) break } @@ -61,8 +73,6 @@ func getCgroupPidsFile() (string, error) { return "", fmt.Errorf("could not find a cgroup for 'pids'") } - pidsMax := fmt.Sprintf(sysPidsMaxFmt, slice) - return pidsMax, nil }