| # Copyright 2012 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| description "mount cgroups on /sys/fs/cgroup" | |
| author "chromium-os-dev@chromium.org" | |
| # Disable OOM killer as we must never fail. | |
| oom score never | |
| start on starting boot-services | |
| task | |
| # To be compatible with how Android container mounts cpusets, we mount | |
| # without prefix (so "cpuset.cpus" turns into "cpus"). | |
| # However, some platforms (like LXC containers on moblab) need the prefix. | |
| # So let platforms override as needed. | |
| env CPUSET_NOPREFIX=true | |
| script | |
| log() { | |
| logger -t "${UPSTART_JOB}" "failed to mount cgroup susbsystem $1" | |
| } | |
| default_mount_opts="noexec,nosuid,nodev" | |
| for subsys in cpu freezer devices cpuacct cpuset memory net_cls; do | |
| # Verify that the subsystem is available on our kernel. | |
| grep -q ${subsys} /proc/cgroups || continue | |
| mkdir -p /sys/fs/cgroup/${subsys} # croslint: disable | |
| mount_opts="${default_mount_opts}" | |
| if [ "${subsys}" = "cpuset" ] && [ "${CPUSET_NOPREFIX}" = true ]; then | |
| mount_opts="${mount_opts},noprefix" | |
| fi | |
| # Mount cpuset cgroup controllers. | |
| if [ "${subsys}" = "cpuset" ]; then | |
| # First try v2 mode, avoids need for cpuset hotplug on kernel >= 4.14. | |
| if ! mount -t cgroup cgroup "/sys/fs/cgroup/${subsys}" \ | |
| -o "${subsys},${mount_opts},cpuset_v2_mode"; then | |
| # If failed try regular cpuset, kernel < 4.14 needs hotplug fixes. | |
| mount -t cgroup cgroup "/sys/fs/cgroup/${subsys}" \ | |
| -o "${subsys},${mount_opts}" || log "${subsys}" | |
| fi | |
| else | |
| # Mount non-cpuset cgroup controllers. | |
| mount -t cgroup cgroup "/sys/fs/cgroup/${subsys}" \ | |
| -o "${subsys},${mount_opts}" || log "${subsys}" | |
| fi | |
| if [ "${subsys}" != "net_cls" ]; then | |
| mkdir -p /sys/fs/cgroup/${subsys}/session_manager_containers \ | |
| # croslint: disable | |
| if id -u android-root 2>/dev/null; then | |
| chown android-root:android-root \ | |
| /sys/fs/cgroup/${subsys}/session_manager_containers \ | |
| # croslint: disable | |
| fi | |
| if id -u user-containers 2>/dev/null; then | |
| mkdir -p /sys/fs/cgroup/${subsys}/user_containers # croslint: disable | |
| chown user-containers:user-containers \ | |
| /sys/fs/cgroup/${subsys}/user_containers # croslint: disable | |
| if [ "${subsys}" = "freezer" ]; then | |
| chown power:power \ | |
| /sys/fs/cgroup/freezer/user_containers/freezer.state \ | |
| # croslint: disable | |
| fi | |
| fi | |
| mkdir -p /sys/fs/cgroup/${subsys}/chronos_containers # croslint: disable | |
| chown chronos:chronos /sys/fs/cgroup/${subsys}/chronos_containers \ | |
| # croslint: disable | |
| fi | |
| # powerd needs to be able to freeze each child of the root freezer, so give | |
| # it ownership of the freezer.state file (and only that file). | |
| if [ "${subsys}" = "freezer" ]; then | |
| chown power:power \ | |
| /sys/fs/cgroup/${subsys}/session_manager_containers/freezer.state \ | |
| # croslint: disable | |
| chown power:power \ | |
| /sys/fs/cgroup/${subsys}/chronos_containers/freezer.state \ | |
| # croslint: disable | |
| fi | |
| done | |
| # Create and set up Chrome cpusets with default settings | |
| # (all cpus, all mems). | |
| cpuset_root_dir="/sys/fs/cgroup/cpuset" | |
| if [ -d "${cpuset_root_dir}" ]; then | |
| cpuset_root_cpus=$(cat "${cpuset_root_dir}/cpus") | |
| cpuset_root_mems=$(cat "${cpuset_root_dir}/mems") | |
| for cset in chrome chrome/urgent chrome/non-urgent; do | |
| cset_dir="${cpuset_root_dir}/${cset}" | |
| mkdir -p "${cset_dir}" # croslint: disable | |
| chown chronos:chronos "${cset_dir}/cgroup.procs" # croslint: disable | |
| chown chronos:chronos "${cset_dir}/tasks" # croslint: disable | |
| echo "${cpuset_root_cpus}" > "${cset_dir}/cpus" | |
| echo "${cpuset_root_mems}" > "${cset_dir}/mems" | |
| done | |
| for cset in user_space user_space/urgent user_space/non-urgent \ | |
| user_space/media; do | |
| cset_dir="${cpuset_root_dir}/${cset}" | |
| mkdir -p "${cset_dir}" # croslint: disable | |
| echo "${cpuset_root_cpus}" > "${cset_dir}/cpus" | |
| echo "${cpuset_root_mems}" > "${cset_dir}/mems" | |
| done | |
| # Adjust cpusets of the rest of the created containers to | |
| # also have all available cpus and all mems. | |
| for cset in session_manager_containers chronos_containers user_containers; | |
| do | |
| cset_dir="${cpuset_root_dir}/${cset}" | |
| if [ -d "${cset_dir}" ]; then | |
| echo "${cpuset_root_cpus}" > "${cset_dir}/cpus" | |
| echo "${cpuset_root_mems}" > "${cset_dir}/mems" | |
| fi | |
| done | |
| fi | |
| # Create resourced's parent cgroup. Sub-cgroups are created and managed by | |
| # resourced at runtime. | |
| resourced_cpu_cgroup=/sys/fs/cgroup/cpu/resourced | |
| resourced_cpuset_cgroup=/sys/fs/cgroup/cpuset/resourced | |
| mkdir -p "${resourced_cpu_cgroup}" "${resourced_cpuset_cgroup}" \ | |
| # croslint: disable | |
| chown -R resourced "${resourced_cpu_cgroup}" "${resourced_cpuset_cgroup}" \ | |
| # croslint: disable | |
| # Create a cpu cgroup for each VM type. Default cpu.shares is 1024. Limit the | |
| # VMs to 7/8ths of that initially. | |
| cgroup_dir="/sys/fs/cgroup/cpu" | |
| for vm_type in termina plugin ; do | |
| mkdir -p "${cgroup_dir}/${vm_type}" \ | |
| "${cgroup_dir}/${vm_type}-vcpus" # croslint: disable | |
| echo 896 > "${cgroup_dir}/${vm_type}/cpu.shares" | |
| echo 896 > "${cgroup_dir}/${vm_type}-vcpus/cpu.shares" | |
| done | |
| end script |