Skip to content

Commit fe0669b

Browse files
committed
don't enable threaded mode by default
Because in threaded mode, we can't enable the memory controller -- it isn't thread-aware. Signed-off-by: lifubang <lifubang@acmcoder.com>
1 parent 6621af8 commit fe0669b

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

libcontainer/cgroups/fs2/create.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ func neededControllers(cgroup *configs.Cgroup) ([]string, error) {
6363
return list, nil
6464
}
6565

66+
// containsDomainController returns whether the current config contains domain controller or not.
67+
// Refer to: http://man7.org/linux/man-pages/man7/cgroups.7.html
68+
// As at Linux 4.19, the following controllers are threaded: cpu, perf_event, and pids.
69+
func containsDomainController(cg *configs.Cgroup) bool {
70+
return isMemorySet(cg) || isIoSet(cg) || isCpuSet(cg) || isHugeTlbSet(cg)
71+
}
72+
6673
// CreateCgroupPath creates cgroupv2 path, enabling all the
6774
// needed controllers in the process.
6875
func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
@@ -95,10 +102,34 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) {
95102
}
96103
}()
97104
}
98-
// Write cgroup.type explicitly.
99-
// Otherwise ENOTSUP may happen.
100-
cgType := filepath.Join(current, "cgroup.type")
101-
_ = ioutil.WriteFile(cgType, []byte("threaded"), 0644)
105+
cgTypeFile := filepath.Join(current, "cgroup.type")
106+
cgType, _ := ioutil.ReadFile(cgTypeFile)
107+
switch strings.TrimSpace(string(cgType)) {
108+
// If the cgroup is in an invalid mode (usually this means there's an internal
109+
// process in the cgroup tree, because we created a cgroup under an
110+
// already-populated-by-other-processes cgroup), then we have to error out if
111+
// the user requested controllers which are not thread-aware. However, if all
112+
// the controllers requested are thread-aware we can simply put the cgroup into
113+
// threaded mode.
114+
case "domain invalid":
115+
if containsDomainController(c) {
116+
return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in an invalid state", current)
117+
} else {
118+
// Not entirely correct (in theory we'd always want to be a domain --
119+
// since that means we're a properly delegated cgroup subtree) but in
120+
// this case there's not much we can do and it's better than giving an
121+
// error.
122+
_ = ioutil.WriteFile(cgTypeFile, []byte("threaded"), 0644)
123+
}
124+
// If the cgroup is in (threaded) or (domain threaded) mode, we can only use thread-aware controllers
125+
// (and you cannot usually take a cgroup out of threaded mode).
126+
case "domain threaded":
127+
fallthrough
128+
case "threaded":
129+
if containsDomainController(c) {
130+
return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in %s mode", current, strings.TrimSpace(string(cgType)))
131+
}
132+
}
102133
}
103134
// enable needed controllers
104135
if i < len(elements)-1 {

tests/rootless.sh

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,6 @@ function enable_cgroup() {
9999
chown root:rootless "$CGROUP_MOUNT/$CGROUP_PATH" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.subtree_control" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.procs" "$CGROUP_MOUNT/cgroup.procs"
100100
chmod g+rwx "$CGROUP_MOUNT/$CGROUP_PATH"
101101
chmod g+rw "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.subtree_control" "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.procs" "$CGROUP_MOUNT/cgroup.procs"
102-
# Fix up cgroup.type.
103-
echo threaded > "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.type"
104-
# Make sure cgroup.type doesn't contain "invalid". Otherwise write ops will fail with ENOTSUP.
105-
# See http://man7.org/linux/man-pages/man7/cgroups.7.html
106-
if grep -qw invalid "$CGROUP_MOUNT/$CGROUP_PATH/cgroup.type"; then
107-
exit 1
108-
fi
109102
fi
110103
}
111104

0 commit comments

Comments
 (0)