From 3de6395ae3b8780ab501f3cf8688e1cb2a9f0243 Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Tue, 28 Nov 2017 17:14:33 -0600 Subject: [PATCH] split cgroups mounting out of sysfs This is neceessary to allow cgroups to be mounted in an lxc/lxd container. Fixes https://github.com/openrc/openrc/issues/187 --- NEWS.md | 17 ++++++ init.d/.gitignore | 1 + init.d/Makefile | 7 ++- init.d/cgroups.in | 147 +++++++++++++++++++++++++++++++++++++++++++++ init.d/sysfs.in | 112 ---------------------------------- runlevels/Makefile | 2 +- 6 files changed, 170 insertions(+), 116 deletions(-) create mode 100644 init.d/cgroups.in diff --git a/NEWS.md b/NEWS.md index 9982e9bd..70a6b4db 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,23 @@ the information in this file is in reverse order. ## OpenRC 0.35 +In this version, the cgroups mounting logic has been moved from the +sysfs service to the cgroups service. This was done so cgroups can be +mounted inside an lxc/lxd container without using the other parts of the +sysfs service. + +?As a result of this change, if you are upgrading, you need to add +cgroups to your sysinit runlevel by running the following command as +root: + +``` +# rc-update add cgroups sysinit +``` + +For more information, see the following issue: + +https://github.com/openrc/openrc/issues/187 + Consider this your second notification with regard to /etc/mtab being a file instead of a symbolic link. diff --git a/init.d/.gitignore b/init.d/.gitignore index 95ad4aad..90abdbbe 100644 --- a/init.d/.gitignore +++ b/init.d/.gitignore @@ -1,5 +1,6 @@ agetty binfmt +cgroups modules-load bootmisc fsck diff --git a/init.d/Makefile b/init.d/Makefile index c6cdbd97..9c97e1ed 100644 --- a/init.d/Makefile +++ b/init.d/Makefile @@ -21,9 +21,10 @@ SRCS-FreeBSD= hostid.in modules.in moused.in newsyslog.in pf.in rarpd.in \ SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \ modules-load.in mixer.in nscd.in powerd.in syscons.in -SRCS-Linux= agetty.in binfmt.in devfs.in dmesg.in hwclock.in consolefont.in \ - keymaps.in killprocs.in modules.in modules-load.in mount-ro.in mtab.in \ - numlock.in procfs.in net-online.in sysfs.in termencoding.in +SRCS-Linux= agetty.in binfmt.in devfs.in cgroups.in dmesg.in hwclock.in \ + consolefont.in keymaps.in killprocs.in modules.in modules-load.in \ + mount-ro.in mtab.in numlock.in procfs.in net-online.in sysfs.in \ +termencoding.in # Generic BSD scripts SRCS-NetBSD= hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \ diff --git a/init.d/cgroups.in b/init.d/cgroups.in new file mode 100644 index 00000000..fe21904c --- /dev/null +++ b/init.d/cgroups.in @@ -0,0 +1,147 @@ +#!@SBINDIR@/openrc-run +# Copyright (c) 2017 The OpenRC Authors. +# See the Authors file at the top-level directory of this distribution and +# https://github.com/OpenRC/openrc/blob/master/AUTHORS +# +# This file is part of OpenRC. It is subject to the license terms in +# the LICENSE file found in the top-level directory of this +# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE +# This file may not be copied, modified, propagated, or distributed +# except according to the terms contained in the LICENSE file. + +description="Mount the control groups." + +cgroup_opts=nodev,noexec,nosuid + +depend() +{ + keyword -docker -prefix -systemd-nspawn -vserver + after sysfs +} + +cgroup1_base() +{ + grep -qw cgroup /proc/filesystems || return 0 + if ! mountinfo -q /sys/fs/cgroup; then + ebegin "Mounting cgroup filesystem" + local opts="${cgroup_opts},mode=755,size=${rc_cgroupsize:-10m}" + mount -n -t tmpfs -o "${opts}" cgroup_root /sys/fs/cgroup + eend $? + fi + + if ! mountinfo -q /sys/fs/cgroup/openrc; then + local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh" + mkdir /sys/fs/cgroup/openrc + mount -n -t cgroup \ + -o none,${cgroup_opts},name=openrc,release_agent="$agent" \ + openrc /sys/fs/cgroup/openrc + printf 1 > /sys/fs/cgroup/openrc/notify_on_release + fi + return 0 +} + +cgroup1_controllers() +{ + yesno "${rc_controller_cgroups:-YES}" && [ -e /proc/cgroups ] || return 0 + while read -r name _ _ enabled _; do + case "${enabled}" in + 1) mountinfo -q "/sys/fs/cgroup/${name}" && continue + local x + for x in $rc_cgroup_controllers; do + [ "${name}" = "blkio" ] && [ "${x}" = "io" ] && + continue 2 + [ "${name}" = "${x}" ] && + continue 2 + done + mkdir "/sys/fs/cgroup/${name}" + mount -n -t cgroup -o "${cgroup_opts},${name}" \ + "${name}" "/sys/fs/cgroup/${name}" + ;; + esac + done < /proc/cgroups + return 0 +} + +cgroup2_base() +{ + local base + base="$(cgroup2_find_path)" + mkdir -p "${base}" + mount -t cgroup2 none -o "${cgroup_opts},nsdelegate" "${base}" 2> /dev/null || + mount -t cgroup2 none -o "${cgroup_opts}" "${base}" + return 0 +} + +cgroup2_controllers() +{ + local active cgroup_path x y + cgroup_path="$(cgroup2_find_path)" + [ -z "${cgroup_path}" ] && return 0 + [ -e "${cgroup_path}/cgroup.controllers" ] && + read -r active < "${cgroup_path}/cgroup.controllers" + for x in ${rc_cgroup_controllers}; do + for y in ${active}; do + [ "$x" = "$y" ] && + [ -e "${cgroup_path}/cgroup.subtree_control" ]&& + echo "+${x}" > "${cgroup_path}/cgroup.subtree_control" + done + done + return 0 +} + +cgroups_hybrid() +{ + grep -qw cgroup /proc/filesystems || return 0 + cgroup1_base + if grep -qw cgroup2 /proc/filesystems; then + cgroup2_base + cgroup2_controllers + fi + cgroup1_controllers + return 0 +} + +cgroups_legacy() +{ + grep -qw cgroup /proc/filesystems || return 0 + cgroup1_base + cgroup1_controllers + return 0 +} + +cgroups_unified() +{ + cgroup2_base + cgroup2_controllers + return 0 +} + +mount_cgroups() +{ + case "${rc_cgroup_mode:-hybrid}" in + hybrid) cgroups_hybrid ;; + legacy) cgroups_legacy ;; + unified) cgroups_unified ;; + esac + return 0 +} + +restorecon_cgroups() +{ + if [ -x /sbin/restorecon ]; then + ebegin "Restoring SELinux contexts in /sys/fs/cgroup" + restorecon -rF /sys/fs/cgroup >/dev/null 2>&1 + eend $? + fi + return 0 +} + +start() +{ + # set up kernel support for cgroups + if [ -d /sys/fs/cgroup ]; then + mount_cgroups + restorecon_cgroups + fi + return 0 +} diff --git a/init.d/sysfs.in b/init.d/sysfs.in index 892528ca..f0d02e5c 100644 --- a/init.d/sysfs.in +++ b/init.d/sysfs.in @@ -107,122 +107,11 @@ mount_misc() fi } -cgroup1_base() -{ - grep -qw cgroup /proc/filesystems || return 0 - if ! mountinfo -q /sys/fs/cgroup; then - ebegin "Mounting cgroup filesystem" - local opts="${sysfs_opts},mode=755,size=${rc_cgroupsize:-10m}" - mount -n -t tmpfs -o "${opts}" cgroup_root /sys/fs/cgroup - eend $? - fi - - if ! mountinfo -q /sys/fs/cgroup/openrc; then - local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh" - mkdir /sys/fs/cgroup/openrc - mount -n -t cgroup \ - -o none,${sysfs_opts},name=openrc,release_agent="$agent" \ - openrc /sys/fs/cgroup/openrc - printf 1 > /sys/fs/cgroup/openrc/notify_on_release - fi - return 0 -} - -cgroup1_controllers() -{ - yesno "${rc_controller_cgroups:-YES}" && [ -e /proc/cgroups ] || return 0 - while read -r name _ _ enabled rest; do - case "${enabled}" in - 1) mountinfo -q "/sys/fs/cgroup/${name}" && continue - local x - for x in $rc_cgroup_controllers; do - [ "${name}" = "blkio" ] && [ "${x}" = "io" ] && - continue 2 - [ "${name}" = "${x}" ] && - continue 2 - done - mkdir "/sys/fs/cgroup/${name}" - mount -n -t cgroup -o "${sysfs_opts},${name}" \ - "${name}" "/sys/fs/cgroup/${name}" - ;; - esac - done < /proc/cgroups - return 0 -} - -cgroup2_base() -{ - local base - base="$(cgroup2_find_path)" - mkdir -p "${base}" - mount -t cgroup2 none -o "${sysfs_opts},nsdelegate" "${base}" 2> /dev/null || - mount -t cgroup2 none -o "${sysfs_opts}" "${base}" - return 0 -} - -cgroup2_controllers() -{ - local active cgroup_path x y - cgroup_path="$(cgroup2_find_path)" - [ -z "${cgroup_path}" ] && return 0 - [ -e "${cgroup_path}/cgroup.controllers" ] && - read -r active < "${cgroup_path}/cgroup.controllers" - for x in ${rc_cgroup_controllers}; do - for y in ${active}; do - [ "$x" = "$y" ] && - [ -e "${cgroup_path}/cgroup.subtree_control" ]&& - echo "+${x}" > "${cgroup_path}/cgroup.subtree_control" - done - done - return 0 -} - -cgroups_hybrid() -{ - grep -qw cgroup /proc/filesystems || return 0 - cgroup1_base - if grep -qw cgroup2 /proc/filesystems; then - cgroup2_base - cgroup2_controllers - fi - cgroup1_controllers - return 0 -} - -cgroups_legacy() -{ - grep -qw cgroup /proc/filesystems || return 0 - cgroup1_base - cgroup1_controllers - return 0 -} - -cgroups_unified() -{ - cgroup2_base - cgroup2_controllers - return 0 -} - -mount_cgroups() -{ - # set up kernel support for cgroups - if [ -d /sys/fs/cgroup ]; then - case "${rc_cgroup_mode:-hybrid}" in - hybrid) cgroups_hybrid ;; - legacy) cgroups_legacy ;; - unified) cgroups_unified ;; - esac - fi - return 0 -} - restorecon_sys() { if [ -x /sbin/restorecon ]; then ebegin "Restoring SELinux contexts in /sys" restorecon -F /sys/devices/system/cpu/online >/dev/null 2>&1 - restorecon -rF /sys/fs/cgroup >/dev/null 2>&1 eend $? fi } @@ -231,7 +120,6 @@ start() { mount_sys mount_misc - mount_cgroups restorecon_sys return 0 } diff --git a/runlevels/Makefile b/runlevels/Makefile index 8007bdda..f000db0d 100644 --- a/runlevels/Makefile +++ b/runlevels/Makefile @@ -38,7 +38,7 @@ BOOT-FreeBSD+= adjkerntz dumpon syscons BOOT-Linux+= binfmt hwclock keymaps modules mtab procfs termencoding SHUTDOWN-Linux= killprocs mount-ro -SYSINIT-Linux= devfs dmesg sysfs +SYSINIT-Linux= devfs cgroups dmesg sysfs # Generic BSD stuff BOOT-NetBSD+= hostid newsyslog savecore syslogd