diff --git a/libcontainer/cgroups/getallpids.go b/libcontainer/cgroups/getallpids.go new file mode 100644 index 000000000..b218744e4 --- /dev/null +++ b/libcontainer/cgroups/getallpids.go @@ -0,0 +1,29 @@ +// +build linux,go1.16 + +package cgroups + +import ( + "io/fs" + "path/filepath" +) + +// GetAllPids returns all pids from the cgroup identified by path, and all its +// sub-cgroups. +func GetAllPids(path string) ([]int, error) { + var pids []int + err := filepath.WalkDir(path, func(p string, d fs.DirEntry, iErr error) error { + if iErr != nil { + return iErr + } + if !d.IsDir() { + return nil + } + cPids, err := readProcsFile(p) + if err != nil { + return err + } + pids = append(pids, cPids...) + return nil + }) + return pids, err +} diff --git a/libcontainer/cgroups/getallpids_go115.go b/libcontainer/cgroups/getallpids_go115.go new file mode 100644 index 000000000..5d55a685d --- /dev/null +++ b/libcontainer/cgroups/getallpids_go115.go @@ -0,0 +1,30 @@ +// +build linux,!go1.16 + +package cgroups + +import ( + "os" + "path/filepath" +) + +// GetAllPids returns all pids, that were added to cgroup at path and to all its +// subcgroups. +func GetAllPids(path string) ([]int, error) { + var pids []int + // collect pids from all sub-cgroups + err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error { + if iErr != nil { + return iErr + } + if !info.IsDir() { + return nil + } + cPids, err := readProcsFile(p) + if err != nil { + return err + } + pids = append(pids, cPids...) + return nil + }) + return pids, err +} diff --git a/libcontainer/cgroups/getallpids_test.go b/libcontainer/cgroups/getallpids_test.go new file mode 100644 index 000000000..b6100686e --- /dev/null +++ b/libcontainer/cgroups/getallpids_test.go @@ -0,0 +1,19 @@ +// +build linux + +package cgroups + +import ( + "testing" +) + +func BenchmarkGetAllPids(b *testing.B) { + total := 0 + for i := 0; i < b.N; i++ { + i, err := GetAllPids("/sys/fs/cgroup") + if err != nil { + b.Fatal(err) + } + total += len(i) + } + b.Logf("iter: %d, total: %d", b.N, total) +} diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 75015d663..b31705bed 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -118,8 +118,8 @@ func GetAllSubsystems() ([]string, error) { return subsystems, nil } -func readProcsFile(file string) ([]int, error) { - f, err := os.Open(file) +func readProcsFile(dir string) ([]int, error) { + f, err := OpenFile(dir, CgroupProcesses, os.O_RDONLY) if err != nil { return nil, err } @@ -336,29 +336,7 @@ func getHugePageSizeFromFilenames(fileNames []string) ([]string, error) { // GetPids returns all pids, that were added to cgroup at path. func GetPids(dir string) ([]int, error) { - return readProcsFile(filepath.Join(dir, CgroupProcesses)) -} - -// GetAllPids returns all pids, that were added to cgroup at path and to all its -// subcgroups. -func GetAllPids(path string) ([]int, error) { - var pids []int - // collect pids from all sub-cgroups - err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error { - if iErr != nil { - return iErr - } - if info.IsDir() || info.Name() != CgroupProcesses { - return nil - } - cPids, err := readProcsFile(p) - if err != nil { - return err - } - pids = append(pids, cPids...) - return nil - }) - return pids, err + return readProcsFile(dir) } // WriteCgroupProc writes the specified pid into the cgroup's cgroup.procs file