Skip to content

Instantly share code, notes, and snippets.

@tianon
Last active August 29, 2015 13:57
Show Gist options
  • Save tianon/9461419 to your computer and use it in GitHub Desktop.
Save tianon/9461419 to your computer and use it in GitHub Desktop.
diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index b40e1a3..3df82c2 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -62,7 +62,15 @@ func GetInitCgroupDir(subsystem string) (string, error) {
return parseCgroupFile(subsystem, f)
}
-func (c *Cgroup) Path(root, subsystem string) (string, error) {
+func (c *Cgroup) Path(subsystem string) (string, error) {
+ root, err := FindCgroupMountpoint(subsystem)
+ if err != nil {
+ return "", err
+ }
+ // We get to handle both "/sys/fs/cgroup" and "/sys/fs/cgroup/devices".
+ if !strings.HasSuffix(root, "/"+subsystem) {
+ root = filepath.Join(root, subsystem)
+ }
cgroup := c.Name
if c.Parent != "" {
cgroup = filepath.Join(c.Parent, cgroup)
@@ -71,11 +79,11 @@ func (c *Cgroup) Path(root, subsystem string) (string, error) {
if err != nil {
return "", err
}
- return filepath.Join(root, subsystem, initPath, cgroup), nil
+ return filepath.Join(root, initPath, cgroup), nil
}
-func (c *Cgroup) Join(root, subsystem string, pid int) (string, error) {
- path, err := c.Path(root, subsystem)
+func (c *Cgroup) Join(subsystem string, pid int) (string, error) {
+ path, err := c.Path(subsystem)
if err != nil {
return "", err
}
@@ -88,9 +96,9 @@ func (c *Cgroup) Join(root, subsystem string, pid int) (string, error) {
return path, nil
}
-func (c *Cgroup) Cleanup(root string) error {
+func (c *Cgroup) Cleanup() error {
get := func(subsystem string) string {
- path, _ := c.Path(root, subsystem)
+ path, _ := c.Path(subsystem)
return path
}
@@ -98,6 +106,7 @@ func (c *Cgroup) Cleanup(root string) error {
get("memory"),
get("devices"),
get("cpu"),
+ get("cpuset"),
} {
os.RemoveAll(path)
}
@@ -130,32 +139,34 @@ func (c *Cgroup) Apply(pid int) error {
// systemd and the dbus api, and one is based on raw cgroup fs operations
// following the pre-single-writer model docs at:
// http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups/
- //
+
// we can pick any subsystem to find the root
cgroupRoot, err := FindCgroupMountpoint("cpu")
if err != nil {
return err
}
- cgroupRoot = filepath.Dir(cgroupRoot)
-
if _, err := os.Stat(cgroupRoot); err != nil {
return fmt.Errorf("cgroups fs not found")
}
- if err := c.setupDevices(cgroupRoot, pid); err != nil {
+
+ if err := c.setupDevices(pid); err != nil {
return err
}
- if err := c.setupMemory(cgroupRoot, pid); err != nil {
+ if err := c.setupMemory(pid); err != nil {
return err
}
- if err := c.setupCpu(cgroupRoot, pid); err != nil {
+ if err := c.setupCpu(pid); err != nil {
+ return err
+ }
+ if err := c.setupCpuSet(pid); err != nil {
return err
}
return nil
}
-func (c *Cgroup) setupDevices(cgroupRoot string, pid int) (err error) {
+func (c *Cgroup) setupDevices(pid int) (err error) {
if !c.DeviceAccess {
- dir, err := c.Join(cgroupRoot, "devices", pid)
+ dir, err := c.Join("devices", pid)
if err != nil {
return err
}
@@ -203,9 +214,9 @@ func (c *Cgroup) setupDevices(cgroupRoot string, pid int) (err error) {
return nil
}
-func (c *Cgroup) setupMemory(cgroupRoot string, pid int) (err error) {
+func (c *Cgroup) setupMemory(pid int) (err error) {
if c.Memory != 0 || c.MemorySwap != 0 {
- dir, err := c.Join(cgroupRoot, "memory", pid)
+ dir, err := c.Join("memory", pid)
if err != nil {
return err
}
@@ -234,10 +245,10 @@ func (c *Cgroup) setupMemory(cgroupRoot string, pid int) (err error) {
return nil
}
-func (c *Cgroup) setupCpu(cgroupRoot string, pid int) (err error) {
+func (c *Cgroup) setupCpu(pid int) (err error) {
// We always want to join the cpu group, to allow fair cpu scheduling
// on a container basis
- dir, err := c.Join(cgroupRoot, "cpu", pid)
+ dir, err := c.Join("cpu", pid)
if err != nil {
return err
}
@@ -248,3 +259,19 @@ func (c *Cgroup) setupCpu(cgroupRoot string, pid int) (err error) {
}
return nil
}
+
+func (c *Cgroup) setupCpuSet(pid int) (err error) {
+ // Necessary in some edge cases, but doesn't hurt the general case.
+ dir, err := c.Join("cpuset", pid)
+ if err != nil {
+ return err
+ }
+ // TODO don't overwrite non-empty files here
+ if err := writeFile(dir, "cpuset.cpus", "0"); err != nil {
+ return err
+ }
+ if err := writeFile(dir, "cpuset.mems", "0"); err != nil {
+ return err
+ }
+ return nil
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment