Skip to content

Commit a67dab0

Browse files
committed
Revert "CreateCgroupPath: only enable needed controllers"
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 <lifubang@acmcoder.com>
1 parent b207d57 commit a67dab0

File tree

2 files changed

+54
-69
lines changed

2 files changed

+54
-69
lines changed

libcontainer/cgroups/fs2/create.go

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fs2
22

33
import (
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.
7574
func 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,

libcontainer/cgroups/fs2/fs2.go

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ func (m *manager) Apply(pid int) error {
7676
// - "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
7777
if m.rootless {
7878
if m.config.Path == "" {
79-
cl, clErr := neededControllers(m.config)
80-
if clErr == nil && len(cl) == 0 {
79+
if blNeed, nErr := needAnyControllers(m.config); nErr == nil && !blNeed {
8180
return nil
8281
}
8382
return errors.Wrap(err, "rootless needs no limits + no cgrouppath when no permission is granted for cgroups")
@@ -175,57 +174,41 @@ func (m *manager) Set(container *configs.Config) error {
175174
if err := m.getControllers(); err != nil {
176175
return err
177176
}
178-
var errs []error
179177
// pids (since kernel 4.5)
180-
if _, ok := m.controllers["pids"]; ok {
181-
if err := setPids(m.dirPath, container.Cgroups); err != nil {
182-
errs = append(errs, err)
183-
}
178+
if err := setPids(m.dirPath, container.Cgroups); err != nil {
179+
return err
184180
}
185181
// memory (since kernel 4.5)
186-
if _, ok := m.controllers["memory"]; ok {
187-
if err := setMemory(m.dirPath, container.Cgroups); err != nil {
188-
errs = append(errs, err)
189-
}
182+
if err := setMemory(m.dirPath, container.Cgroups); err != nil {
183+
return err
190184
}
191185
// io (since kernel 4.5)
192-
if _, ok := m.controllers["io"]; ok {
193-
if err := setIo(m.dirPath, container.Cgroups); err != nil {
194-
errs = append(errs, err)
195-
}
186+
if err := setIo(m.dirPath, container.Cgroups); err != nil {
187+
return err
196188
}
197189
// cpu (since kernel 4.15)
198-
if _, ok := m.controllers["cpu"]; ok {
199-
if err := setCpu(m.dirPath, container.Cgroups); err != nil {
200-
errs = append(errs, err)
201-
}
190+
if err := setCpu(m.dirPath, container.Cgroups); err != nil {
191+
return err
202192
}
203193
// devices (since kernel 4.15, pseudo-controller)
204194
//
205195
// When m.Rootless is true, errors from the device subsystem are ignored because it is really not expected to work.
206196
// However, errors from other subsystems are not ignored.
207197
// see @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error"
208198
if err := setDevices(m.dirPath, container.Cgroups); err != nil && !m.rootless {
209-
errs = append(errs, err)
199+
return err
210200
}
211201
// cpuset (since kernel 5.0)
212-
if _, ok := m.controllers["cpuset"]; ok {
213-
if err := setCpuset(m.dirPath, container.Cgroups); err != nil {
214-
errs = append(errs, err)
215-
}
202+
if err := setCpuset(m.dirPath, container.Cgroups); err != nil {
203+
return err
216204
}
217205
// hugetlb (since kernel 5.6)
218-
if _, ok := m.controllers["hugetlb"]; ok {
219-
if err := setHugeTlb(m.dirPath, container.Cgroups); err != nil {
220-
errs = append(errs, err)
221-
}
206+
if err := setHugeTlb(m.dirPath, container.Cgroups); err != nil {
207+
return err
222208
}
223209
// freezer (since kernel 5.2, pseudo-controller)
224210
if err := setFreezer(m.dirPath, container.Cgroups.Freezer); err != nil {
225-
errs = append(errs, err)
226-
}
227-
if len(errs) > 0 {
228-
return errors.Errorf("error while setting cgroup v2: %+v", errs)
211+
return err
229212
}
230213
m.config = container.Cgroups
231214
return nil

0 commit comments

Comments
 (0)