Skip to content

Commit

Permalink
CreateCgroupPath: only enable needed controllers
Browse files Browse the repository at this point in the history
... on a best-effort basis.

1. Instead of enabling all available controllers, figure out which
   ones are required, and only enable those.

2. Do not return an error early if we can't enable some controllers.

3. If we fail to enable all controllers at once (usually because one of
   them can't be enabled), try enabling them one by one.

Signed-off-by: Kir Kolyshkin <[email protected]>
  • Loading branch information
kolyshkin committed Apr 8, 2020
1 parent 430d891 commit 4ca9810
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 13 deletions.
80 changes: 69 additions & 11 deletions libcontainer/cgroups/fs2/create.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,80 @@
package fs2

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/opencontainers/runc/libcontainer/configs"
)

// CreateCgroupPath creates cgroupv2 path, enabling all the
// available controllers in the process.
func CreateCgroupPath(path string) (Err error) {
if !strings.HasPrefix(path, UnifiedMountpoint) {
return fmt.Errorf("invalid cgroup path %s", path)
func neededControllers(c *configs.Cgroup) []string {
var list []string

if c == nil {
return list
}

// list of all available controllers
const file = UnifiedMountpoint + "/cgroup.controllers"
content, err := ioutil.ReadFile(file)
if err != nil {
return err
return list
}
avail := make(map[string]struct{})
for ctr := range strings.Split(string(content), " ") {
avail[string(ctr)] = struct{}{}
}

// add the controller if available
add := func(controller string) {
if _, ok := avail[controller]; ok {
list = append(list, "+"+controller)
}
}

if c.Resources.PidsLimit != 0 {
add("pids")
}

if c.Resources.MemoryReservation != 0 || c.Resources.Memory != 0 || c.Resources.MemorySwap != 0 {
add("memory")
}

if c.Resources.BlkioWeight != 0 ||
len(c.Resources.BlkioThrottleReadBpsDevice) > 0 ||
len(c.Resources.BlkioThrottleWriteBpsDevice) > 0 ||
len(c.Resources.BlkioThrottleReadIOPSDevice) > 0 ||
len(c.Resources.BlkioThrottleWriteIOPSDevice) > 0 {
add("io")
}

ctrs := bytes.Fields(content)
res := append([]byte("+"), bytes.Join(ctrs, []byte(" +"))...)
if c.Resources.CpuWeight != 0 || c.Resources.CpuMax != "" {
add("cpu")
}

if c.Resources.CpusetCpus != "" || c.Resources.CpusetMems != "" {
add("cpuset")
}

if len(c.Resources.HugetlbLimit) > 0 {
add("hugetlb")
}

return list
}

// CreateCgroupPath creates cgroupv2 path, enabling all the
// needed controllers in the process.
func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
if !strings.HasPrefix(path, UnifiedMountpoint) {
return fmt.Errorf("invalid cgroup path %s", path)
}

ctrs := neededControllers(c)
allCtrs := strings.Join(ctrs, " ")

elements := strings.Split(path, "/")
elements = elements[3:]
Expand All @@ -44,11 +95,18 @@ func CreateCgroupPath(path string) (Err error) {
}()
}
}
// enable needed controllers
if i < len(elements)-1 {
if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), res, 0755); err != nil {
return err
file := filepath.Join(current, "cgroup.subtree_control")
if err := ioutil.WriteFile(file, []byte(allCtrs), 0755); err != nil {
// failed to enable all controllers at once, so let's try
// one by one, ignoring errors as there's nothing we can do
for _, ctr := range ctrs {
_ = ioutil.WriteFile(file, []byte(ctr), 0755)
}
}
}
}

return nil
}
2 changes: 1 addition & 1 deletion libcontainer/cgroups/fs2/fs2.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (m *manager) getControllers() error {
}

func (m *manager) Apply(pid int) error {
if err := CreateCgroupPath(m.dirPath); err != nil {
if err := CreateCgroupPath(m.dirPath, m.config); err != nil {
return err
}
if err := cgroups.WriteCgroupProc(m.dirPath, pid); err != nil && !m.rootless {
Expand Down
2 changes: 1 addition & 1 deletion libcontainer/cgroups/systemd/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (m *unifiedManager) Apply(pid int) error {
if err != nil {
return err
}
if err := fs2.CreateCgroupPath(m.path); err != nil {
if err := fs2.CreateCgroupPath(m.path, m.cgroups); err != nil {
return err
}
return nil
Expand Down

0 comments on commit 4ca9810

Please sign in to comment.