Allow cgroup creation without attaching a pid

Signed-off-by: Buddha Prakash <buddhap@google.com>
This commit is contained in:
Buddha Prakash 2016-07-19 16:33:09 -07:00
parent bd1d3ac048
commit ebe85bf180
3 changed files with 26 additions and 10 deletions

View File

@ -9,7 +9,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"sync" "sync"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
@ -33,7 +32,6 @@ var (
&FreezerGroup{}, &FreezerGroup{},
&NameGroup{GroupName: "name=systemd", Join: true}, &NameGroup{GroupName: "name=systemd", Join: true},
} }
CgroupProcesses = "cgroup.procs"
HugePageSizes, _ = cgroups.GetHugePageSize() HugePageSizes, _ = cgroups.GetHugePageSize()
) )
@ -341,7 +339,7 @@ func (raw *cgroupData) join(subsystem string) (string, error) {
if err := os.MkdirAll(path, 0755); err != nil { if err := os.MkdirAll(path, 0755); err != nil {
return "", err 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 "", err
} }
return path, nil return path, nil

View File

@ -8,7 +8,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "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 // because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems // 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 return err
} }

View File

@ -16,7 +16,10 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
) )
const cgroupNamePrefix = "name=" const (
cgroupNamePrefix = "name="
CgroupProcesses = "cgroup.procs"
)
// https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
func FindCgroupMountpoint(subsystem string) (string, error) { func FindCgroupMountpoint(subsystem string) (string, error) {
@ -239,7 +242,7 @@ func GetInitCgroupDir(subsystem string) (string, error) {
} }
func readProcsFile(dir string) ([]int, 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 { if err != nil {
return nil, err return nil, err
} }
@ -326,8 +329,7 @@ func PathExists(path string) bool {
func EnterPid(cgroupPaths map[string]string, pid int) error { func EnterPid(cgroupPaths map[string]string, pid int) error {
for _, path := range cgroupPaths { for _, path := range cgroupPaths {
if PathExists(path) { if PathExists(path) {
if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), if err := WriteCgroupProc(path, pid); err != nil {
[]byte(strconv.Itoa(pid)), 0700); err != nil {
return err return err
} }
} }
@ -396,7 +398,7 @@ func GetAllPids(path string) ([]int, error) {
// collect pids from all sub-cgroups // collect pids from all sub-cgroups
err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error { err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
dir, file := filepath.Split(p) dir, file := filepath.Split(p)
if file != "cgroup.procs" { if file != CgroupProcesses {
return nil return nil
} }
if iErr != nil { if iErr != nil {
@ -411,3 +413,20 @@ func GetAllPids(path string) ([]int, error) {
}) })
return pids, err 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
}