diff options
author | Christian Brauner <cbrauner@suse.de> | 2016-06-23 13:41:56 +0200 |
---|---|---|
committer | Christian Brauner <cbrauner@suse.de> | 2016-07-09 06:34:11 +0200 |
commit | 0996ef00fb5c0770d49670f81a230fcc2552af89 (patch) | |
tree | 816306f265ce35d08f57044572bac32ca353abb1 /src/nspawn/nspawn.c | |
parent | 3228995c534c4cae609e97502f7c7ca1d4a14840 (diff) |
nspawn: handle cgroup namespaces
(NOTE: Cgroup namespaces work with legacy and unified hierarchies: "This is
completely backward compatible and will be completely invisible to any existing
cgroup users (except for those running inside a cgroup namespace and looking at
/proc/pid/cgroup of tasks outside their namespace.)"
(https://lists.linuxfoundation.org/pipermail/containers/2016-January/036582.html)
So there is no need to special case unified.)
If cgroup namespaces are supported we skip mount_cgroups() in the
outer_child(). Instead, we unshare(CLONE_NEWCGROUP) in the inner_child() and
only then do we call mount_cgroups().
The clean way to handle cgroup namespaces would be to delegate mounting of
cgroups completely to the init system in the container. However, this would
likely break backward compatibility with the UNIFIED_CGROUP_HIERARCHY flag of
systemd-nspawn. Also no cgroupfs would be mounted whenever the user simply
requests a shell and no init is available to mount cgroups. Hence, we introduce
mount_legacy_cgns_supported(). After calling unshare(CLONE_NEWCGROUP) it parses
/proc/self/cgroup to find the mounted controllers and mounts them inside the
new cgroup namespace. This should preserve backward compatibility with the
UNIFIED_CGROUP_HIERARCHY flag and mount a cgroupfs when no init in the
container is running.
Diffstat (limited to 'src/nspawn/nspawn.c')
-rw-r--r-- | src/nspawn/nspawn.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 73c56d7310..9e74a77758 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2594,9 +2594,24 @@ static int inner_child( return -ESRCH; } - r = mount_systemd_cgroup_writable("", arg_unified_cgroup_hierarchy); - if (r < 0) - return r; + if (cg_ns_supported()) { + r = unshare(CLONE_NEWCGROUP); + if (r < 0) + return log_error_errno(errno, "Failed to unshare cgroup namespace"); + r = mount_cgroups( + "", + arg_unified_cgroup_hierarchy, + arg_userns_mode != USER_NAMESPACE_NO, + arg_uid_shift, + arg_uid_range, + arg_selinux_apifs_context); + if (r < 0) + return r; + } else { + r = mount_systemd_cgroup_writable("", arg_unified_cgroup_hierarchy); + if (r < 0) + return r; + } r = reset_uid_gid(); if (r < 0) @@ -2978,15 +2993,17 @@ static int outer_child( if (r < 0) return r; - r = mount_cgroups( - directory, - arg_unified_cgroup_hierarchy, - arg_userns_mode != USER_NAMESPACE_NO, - arg_uid_shift, - arg_uid_range, - arg_selinux_apifs_context); - if (r < 0) - return r; + if (!cg_ns_supported()) { + r = mount_cgroups( + directory, + arg_unified_cgroup_hierarchy, + arg_userns_mode != USER_NAMESPACE_NO, + arg_uid_shift, + arg_uid_range, + arg_selinux_apifs_context); + if (r < 0) + return r; + } r = mount_move_root(directory); if (r < 0) |