util: support systems using the new cgroup v2 structure

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 <m.roeder@yieldlab.de>
This commit is contained in:
Marcus Röder 2022-05-05 10:58:54 +02:00 committed by mergify[bot]
parent 1197b94149
commit a95a6213eb

View File

@ -28,15 +28,18 @@ import (
const ( const (
procCgroup = "/proc/self/cgroup" procCgroup = "/proc/self/cgroup"
sysPidsMaxFmt = "/sys/fs/cgroup/pids%s/pids.max" 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 // getCgroupPidsFile return the cgroups "pids.max" file of the
// // current process
// find the line containing the pids group from the /proc/self/cgroup file // For cgroup v1, find the line containing the pids group from the /proc/self/cgroup file
// $ grep 'pids' /proc/self/cgroup // $ grep ':pids:' /proc/self/cgroup
// 7:pids:/kubepods.slice/kubepods-besteffort.slice/....scope // 7:pids:/kubepods.slice/kubepods-besteffort.slice/....scope
// $ cat /sys/fs/cgroup/pids + *.scope + /pids.max. // $ 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) { func getCgroupPidsFile() (string, error) {
cgroup, err := os.Open(procCgroup) cgroup, err := os.Open(procCgroup)
if err != nil { if err != nil {
@ -44,6 +47,7 @@ func getCgroupPidsFile() (string, error) {
} }
defer cgroup.Close() // #nosec: error on close is not critical here defer cgroup.Close() // #nosec: error on close is not critical here
pidsMax := ""
scanner := bufio.NewScanner(cgroup) scanner := bufio.NewScanner(cgroup)
var slice string var slice string
for scanner.Scan() { for scanner.Scan() {
@ -51,8 +55,16 @@ func getCgroupPidsFile() (string, error) {
if parts == nil || len(parts) < 3 { if parts == nil || len(parts) < 3 {
continue 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" { if parts[1] == "pids" {
slice = parts[2] slice = parts[2]
pidsMax = fmt.Sprintf(sysPidsMaxFmtCgroupV1, slice)
break break
} }
@ -61,8 +73,6 @@ func getCgroupPidsFile() (string, error) {
return "", fmt.Errorf("could not find a cgroup for 'pids'") return "", fmt.Errorf("could not find a cgroup for 'pids'")
} }
pidsMax := fmt.Sprintf(sysPidsMaxFmt, slice)
return pidsMax, nil return pidsMax, nil
} }