Skip to content

Commit

Permalink
Revert "CreateCgroupPath: only enable needed controllers"
Browse files Browse the repository at this point in the history
1. Partially revert "CreateCgroupPath: only enable needed controllers"
If we update a resource which did not limited in the beginning,
it will have no effective.
2. Returns err if we use an non enabled controller,
or else the user may feel success, but actually there are no effective.

Signed-off-by: lifubang <[email protected]>
  • Loading branch information
lifubang committed May 13, 2020
1 parent 85d4264 commit 4e2499e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 48 deletions.
37 changes: 22 additions & 15 deletions libcontainer/cgroups/fs2/create.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fs2

import (
"bytes"
"fmt"
"io/ioutil"
"os"
Expand All @@ -10,24 +11,27 @@ import (
"github.com/opencontainers/runc/libcontainer/configs"
)

// neededControllers returns the string to write to cgroup.subtree_control,
// containing the list of controllers to enable (for example, "+cpu +pids"),
func supportedControllers(cgroup *configs.Cgroup) ([]byte, error) {
const file = UnifiedMountpoint + "/cgroup.controllers"
return ioutil.ReadFile(file)
}

// neededControllers returns the number of controllers to enable,
// based on (1) controllers available and (2) resources that are being set.
//
// The resulting string does not include "pseudo" controllers such as
// "freezer" and "devices".
func neededControllers(cgroup *configs.Cgroup) ([]string, error) {
var list []string
func neededControllers(cgroup *configs.Cgroup) (int, error) {
count := 0

if cgroup == nil {
return list, nil
return count, nil
}

// list of all available controllers
const file = UnifiedMountpoint + "/cgroup.controllers"
content, err := ioutil.ReadFile(file)
content, err := supportedControllers(cgroup)
if err != nil {
return list, err
return count, err
}
avail := make(map[string]struct{})
for _, ctr := range strings.Fields(string(content)) {
Expand All @@ -37,7 +41,7 @@ func neededControllers(cgroup *configs.Cgroup) ([]string, error) {
// add the controller if available
add := func(controller string) {
if _, ok := avail[controller]; ok {
list = append(list, "+"+controller)
count++
}
}

Expand All @@ -60,7 +64,7 @@ func neededControllers(cgroup *configs.Cgroup) ([]string, error) {
add("hugetlb")
}

return list, nil
return count, nil
}

// containsDomainController returns whether the current config contains domain controller or not.
Expand All @@ -77,11 +81,13 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
return fmt.Errorf("invalid cgroup path %s", path)
}

ctrs, err := neededControllers(c)
content, err := supportedControllers(c)
if err != nil {
return err
}
allCtrs := strings.Join(ctrs, " ")

ctrs := bytes.Fields(content)
res := append([]byte("+"), bytes.Join(ctrs, []byte(" +"))...)

elements := strings.Split(path, "/")
elements = elements[3:]
Expand Down Expand Up @@ -134,10 +140,11 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
// enable needed controllers
if i < len(elements)-1 {
file := filepath.Join(current, "cgroup.subtree_control")
if err := ioutil.WriteFile(file, []byte(allCtrs), 0644); err != nil {
if err := ioutil.WriteFile(file, res, 0644); err != nil {
// try write one by one
for _, ctr := range ctrs {
_ = ioutil.WriteFile(file, []byte(ctr), 0644)
allCtrs := bytes.Split(res, []byte(" "))
for _, ctr := range allCtrs {
_ = ioutil.WriteFile(file, ctr, 0644)
}
}
// Some controllers might not be enabled when rootless or containerized,
Expand Down
46 changes: 15 additions & 31 deletions libcontainer/cgroups/fs2/fs2.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (m *manager) Apply(pid int) error {
if m.rootless {
if m.config.Path == "" {
cl, clErr := neededControllers(m.config)
if clErr == nil && len(cl) == 0 {
if clErr == nil && cl == 0 {
return nil
}
return errors.Wrap(err, "rootless needs no limits + no cgrouppath when no permission is granted for cgroups")
Expand Down Expand Up @@ -175,57 +175,41 @@ func (m *manager) Set(container *configs.Config) error {
if err := m.getControllers(); err != nil {
return err
}
var errs []error
// pids (since kernel 4.5)
if _, ok := m.controllers["pids"]; ok {
if err := setPids(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setPids(m.dirPath, container.Cgroups); err != nil {
return err
}
// memory (since kernel 4.5)
if _, ok := m.controllers["memory"]; ok {
if err := setMemory(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setMemory(m.dirPath, container.Cgroups); err != nil {
return err
}
// io (since kernel 4.5)
if _, ok := m.controllers["io"]; ok {
if err := setIo(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setIo(m.dirPath, container.Cgroups); err != nil {
return err
}
// cpu (since kernel 4.15)
if _, ok := m.controllers["cpu"]; ok {
if err := setCpu(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setCpu(m.dirPath, container.Cgroups); err != nil {
return err
}
// devices (since kernel 4.15, pseudo-controller)
//
// When m.Rootless is true, errors from the device subsystem are ignored because it is really not expected to work.
// However, errors from other subsystems are not ignored.
// see @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
if err := setDevices(m.dirPath, container.Cgroups); err != nil && !m.rootless {
errs = append(errs, err)
return err
}
// cpuset (since kernel 5.0)
if _, ok := m.controllers["cpuset"]; ok {
if err := setCpuset(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setCpuset(m.dirPath, container.Cgroups); err != nil {
return err
}
// hugetlb (since kernel 5.6)
if _, ok := m.controllers["hugetlb"]; ok {
if err := setHugeTlb(m.dirPath, container.Cgroups); err != nil {
errs = append(errs, err)
}
if err := setHugeTlb(m.dirPath, container.Cgroups); err != nil {
return err
}
// freezer (since kernel 5.2, pseudo-controller)
if err := setFreezer(m.dirPath, container.Cgroups.Freezer); err != nil {
errs = append(errs, err)
}
if len(errs) > 0 {
return errors.Errorf("error while setting cgroup v2: %+v", errs)
return err
}
m.config = container.Cgroups
return nil
Expand Down
6 changes: 4 additions & 2 deletions libcontainer/cgroups/fs2/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ func setMemory(dirPath string, cgroup *configs.Cgroup) error {
// memory and memorySwap set to the same value -- disable swap
swapStr = "0"
}
if err := fscommon.WriteFile(dirPath, "memory.swap.max", swapStr); err != nil {
return err
if swapStr != "" {
if err := fscommon.WriteFile(dirPath, "memory.swap.max", swapStr); err != nil {
return err
}
}

if val := numToStr(cgroup.Resources.Memory); val != "" {
Expand Down

0 comments on commit 4e2499e

Please sign in to comment.