11package fs2
22
33import (
4+ "bytes"
45 "fmt"
56 "io/ioutil"
67 "os"
@@ -10,57 +11,56 @@ import (
1011 "github.com/opencontainers/runc/libcontainer/configs"
1112)
1213
13- // neededControllers returns the string to write to cgroup.subtree_control,
14- // containing the list of controllers to enable (for example, "+cpu +pids"),
14+ func supportedControllers (cgroup * configs.Cgroup ) ([]byte , error ) {
15+ const file = UnifiedMountpoint + "/cgroup.controllers"
16+ return ioutil .ReadFile (file )
17+ }
18+
19+ // needAnyControllers returns whether we enable some supported controllers or not,
1520// based on (1) controllers available and (2) resources that are being set.
16- //
17- // The resulting string does not include "pseudo" controllers such as
21+ // We don't check "pseudo" controllers such as
1822// "freezer" and "devices".
19- func neededControllers (cgroup * configs.Cgroup ) ([]string , error ) {
20- var list []string
21-
23+ func needAnyControllers (cgroup * configs.Cgroup ) (bool , error ) {
2224 if cgroup == nil {
23- return list , nil
25+ return false , nil
2426 }
2527
2628 // list of all available controllers
27- const file = UnifiedMountpoint + "/cgroup.controllers"
28- content , err := ioutil .ReadFile (file )
29+ content , err := supportedControllers (cgroup )
2930 if err != nil {
30- return list , err
31+ return false , err
3132 }
3233 avail := make (map [string ]struct {})
3334 for _ , ctr := range strings .Fields (string (content )) {
3435 avail [ctr ] = struct {}{}
3536 }
3637
37- // add the controller if available
38- add := func (controller string ) {
39- if _ , ok := avail [controller ]; ok {
40- list = append (list , "+" + controller )
41- }
38+ // check whether the controller if available or not
39+ have := func (controller string ) bool {
40+ _ , ok := avail [controller ]
41+ return ok
4242 }
4343
44- if isPidsSet (cgroup ) {
45- add ( "pids" )
44+ if isPidsSet (cgroup ) && have ( "pids" ) {
45+ return true , nil
4646 }
47- if isMemorySet (cgroup ) {
48- add ( "memory" )
47+ if isMemorySet (cgroup ) && have ( "memory" ) {
48+ return true , nil
4949 }
50- if isIoSet (cgroup ) {
51- add ( "io" )
50+ if isIoSet (cgroup ) && have ( "io" ) {
51+ return true , nil
5252 }
53- if isCpuSet (cgroup ) {
54- add ( "cpu" )
53+ if isCpuSet (cgroup ) && have ( "cpu" ) {
54+ return true , nil
5555 }
56- if isCpusetSet (cgroup ) {
57- add ( "cpuset" )
56+ if isCpusetSet (cgroup ) && have ( "cpuset" ) {
57+ return true , nil
5858 }
59- if isHugeTlbSet (cgroup ) {
60- add ( "hugetlb" )
59+ if isHugeTlbSet (cgroup ) && have ( "hugetlb" ) {
60+ return true , nil
6161 }
6262
63- return list , nil
63+ return false , nil
6464}
6565
6666// containsDomainController returns whether the current config contains domain controller or not.
@@ -70,18 +70,19 @@ func containsDomainController(cg *configs.Cgroup) bool {
7070 return isMemorySet (cg ) || isIoSet (cg ) || isCpuSet (cg ) || isHugeTlbSet (cg )
7171}
7272
73- // CreateCgroupPath creates cgroupv2 path, enabling all the
74- // needed controllers in the process.
73+ // CreateCgroupPath creates cgroupv2 path, enabling all the supported controllers.
7574func CreateCgroupPath (path string , c * configs.Cgroup ) (Err error ) {
7675 if ! strings .HasPrefix (path , UnifiedMountpoint ) {
7776 return fmt .Errorf ("invalid cgroup path %s" , path )
7877 }
7978
80- ctrs , err := neededControllers (c )
79+ content , err := supportedControllers (c )
8180 if err != nil {
8281 return err
8382 }
84- allCtrs := strings .Join (ctrs , " " )
83+
84+ ctrs := bytes .Fields (content )
85+ res := append ([]byte ("+" ), bytes .Join (ctrs , []byte (" +" ))... )
8586
8687 elements := strings .Split (path , "/" )
8788 elements = elements [3 :]
@@ -131,13 +132,14 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
131132 }
132133 }
133134 }
134- // enable needed controllers
135+ // enable all supported controllers
135136 if i < len (elements )- 1 {
136137 file := filepath .Join (current , "cgroup.subtree_control" )
137- if err := ioutil .WriteFile (file , [] byte ( allCtrs ) , 0644 ); err != nil {
138+ if err := ioutil .WriteFile (file , res , 0644 ); err != nil {
138139 // try write one by one
139- for _ , ctr := range ctrs {
140- _ = ioutil .WriteFile (file , []byte (ctr ), 0644 )
140+ allCtrs := bytes .Split (res , []byte (" " ))
141+ for _ , ctr := range allCtrs {
142+ _ = ioutil .WriteFile (file , ctr , 0644 )
141143 }
142144 }
143145 // Some controllers might not be enabled when rootless or containerized,
0 commit comments