runc/cgroups/utils.go

94 lines
1.7 KiB
Go

package cgroups
import (
"bufio"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/dotcloud/docker/pkg/mount"
)
// https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
func FindCgroupMountpoint(subsystem string) (string, error) {
mounts, err := mount.GetMounts()
if err != nil {
return "", err
}
for _, mount := range mounts {
if mount.Fstype == "cgroup" {
for _, opt := range strings.Split(mount.VfsOpts, ",") {
if opt == subsystem {
return mount.Mountpoint, nil
}
}
}
}
return "", ErrNotFound
}
// Returns the relative path to the cgroup docker is running in.
func GetThisCgroupDir(subsystem string) (string, error) {
f, err := os.Open("/proc/self/cgroup")
if err != nil {
return "", err
}
defer f.Close()
return parseCgroupFile(subsystem, f)
}
func GetInitCgroupDir(subsystem string) (string, error) {
f, err := os.Open("/proc/1/cgroup")
if err != nil {
return "", err
}
defer f.Close()
return parseCgroupFile(subsystem, f)
}
func ReadProcsFile(dir string) ([]int, error) {
f, err := os.Open(filepath.Join(dir, "cgroup.procs"))
if err != nil {
return nil, err
}
defer f.Close()
var (
s = bufio.NewScanner(f)
out = []int{}
)
for s.Scan() {
if t := s.Text(); t != "" {
pid, err := strconv.Atoi(t)
if err != nil {
return nil, err
}
out = append(out, pid)
}
}
return out, nil
}
func parseCgroupFile(subsystem string, r io.Reader) (string, error) {
s := bufio.NewScanner(r)
for s.Scan() {
if err := s.Err(); err != nil {
return "", err
}
text := s.Text()
parts := strings.Split(text, ":")
for _, subs := range strings.Split(parts[1], ",") {
if subs == subsystem {
return parts[2], nil
}
}
}
return "", ErrNotFound
}