diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go index 633ab0427..e7a629dc3 100644 --- a/libcontainer/cgroups/fs/apply_raw.go +++ b/libcontainer/cgroups/fs/apply_raw.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "os" "path/filepath" - "strconv" "sync" "github.com/opencontainers/runc/libcontainer/cgroups" @@ -33,7 +32,6 @@ var ( &FreezerGroup{}, &NameGroup{GroupName: "name=systemd", Join: true}, } - CgroupProcesses = "cgroup.procs" HugePageSizes, _ = cgroups.GetHugePageSize() ) @@ -341,7 +339,7 @@ func (raw *cgroupData) join(subsystem string) (string, error) { if err := os.MkdirAll(path, 0755); err != nil { return "", err } - if err := writeFile(path, CgroupProcesses, strconv.Itoa(raw.pid)); err != nil { + if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil { return "", err } return path, nil diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go index cbe62bd98..29265c70e 100644 --- a/libcontainer/cgroups/fs/cpuset.go +++ b/libcontainer/cgroups/fs/cpuset.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "os" "path/filepath" - "strconv" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" @@ -67,7 +66,7 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro } // because we are not using d.join we need to place the pid into the procs file // unlike the other subsystems - if err := writeFile(dir, "cgroup.procs", strconv.Itoa(pid)); err != nil { + if err := cgroups.WriteCgroupProc(dir, pid); err != nil { return err } diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 1a7c4e1a0..d43270032 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -16,7 +16,10 @@ import ( "github.com/docker/go-units" ) -const cgroupNamePrefix = "name=" +const ( + cgroupNamePrefix = "name=" + CgroupProcesses = "cgroup.procs" +) // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt func FindCgroupMountpoint(subsystem string) (string, error) { @@ -239,7 +242,7 @@ func GetInitCgroupDir(subsystem string) (string, error) { } func readProcsFile(dir string) ([]int, error) { - f, err := os.Open(filepath.Join(dir, "cgroup.procs")) + f, err := os.Open(filepath.Join(dir, CgroupProcesses)) if err != nil { return nil, err } @@ -326,8 +329,7 @@ func PathExists(path string) bool { func EnterPid(cgroupPaths map[string]string, pid int) error { for _, path := range cgroupPaths { if PathExists(path) { - if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), - []byte(strconv.Itoa(pid)), 0700); err != nil { + if err := WriteCgroupProc(path, pid); err != nil { return err } } @@ -396,7 +398,7 @@ func GetAllPids(path string) ([]int, error) { // collect pids from all sub-cgroups err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error { dir, file := filepath.Split(p) - if file != "cgroup.procs" { + if file != CgroupProcesses { return nil } if iErr != nil { @@ -411,3 +413,20 @@ func GetAllPids(path string) ([]int, error) { }) return pids, err } + +// WriteCgroupProc writes the specified pid into the cgroup's cgroup.procs file +func WriteCgroupProc(dir string, pid int) error { + // Normally dir should not be empty, one case is that cgroup subsystem + // is not mounted, we will get empty dir, and we want it fail here. + if dir == "" { + return fmt.Errorf("no such directory for %s", CgroupProcesses) + } + + // Dont attach any pid to the cgroup if -1 is specified as a pid + if pid != -1 { + if err := ioutil.WriteFile(filepath.Join(dir, CgroupProcesses), []byte(strconv.Itoa(pid)), 0700); err != nil { + return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err) + } + } + return nil +}