From e5d96f93d0de60ca5fe2f30c09aef449e39e3e89 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Sun, 24 Aug 2008 20:12:08 +0000 Subject: [PATCH] cgroup support. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2771 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- doc/configuration.xml | 59 ++++++++++++++++++++++++++++++ scripts/vserver.functions | 93 +++++++++++++++++++++++++++++++++++++++++++++++ scripts/vserver.start | 1 + scripts/vserver.stop | 1 + sysv/util-vserver | 13 +++++++ 5 files changed, 167 insertions(+) diff --git a/doc/configuration.xml b/doc/configuration.xml index 729a197..fe9bfe6 100644 --- a/doc/configuration.xml +++ b/doc/configuration.xml @@ -305,6 +305,41 @@ interface will be executed. The default /etc/resolv.conf file. + + + +This directory contains cgroup settings which should be applied to all guests. +See your kernel documentation for what settings are valid with your +configuration. + + + +The directory to mount the cgroup hierarchy at. The default is /dev/cgroup. + + + + +Comma-separated list of subsystems to enable on the cgroup mount point. +The default is "all". + + + + +Some subsystems start out with clean slates, making it impossible to use the +cgroup before certain things have been set. This is true for e.g. the cpuset +subsystem. This file contains a list of filenames which should be explicitly +inherited from the parent (root) cgroup, if not overridden elsewhere. +The default is cpuset.cpus and cpuset.mems. + + + + +If this file exists, all guests will be put in one cgroup named after the +contents of this file. The default is to put each guest in a cgroup named the +same thing as the guest. + + + @@ -1619,5 +1654,29 @@ Puts the guest in a cpuset. Required entries are name, cpus and mems. The IO scheduling priority to use for this guest (see ionice(1)). + + + +This directory contains cgroup settings to be applied to this guest. +See your kernel documentation for what settings are valid with your +configuration. + + + +If this file exists, the guest will be put in a cgroup named after the +contents of this file. The default is to name the cgroup the same thing as the +guest, unless +.defaults/cgroup/name says +otherwise. + + + + + +If this file exists, +.defaults/cgroup will be ignored +for this guest. + + diff --git a/scripts/vserver.functions b/scripts/vserver.functions index 238c4b8..d5eeda5 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -71,6 +71,10 @@ N_CONTEXT= SILENT_OPT= +CGROUP_MNT=/dev/cgroup +CGROUP_SUBSYS=all +declare -a CGROUP_INHERIT=( cpuset.cpus cpuset.mems ) + : ${VSERVER_NAME:=$(basename "$VSERVER_DIR")} if test -e "$VSERVER_DIR"/noisy -o -n "$OPTION_VERBOSE"; then @@ -831,6 +835,7 @@ function generateOptions _generateTagOptions "$1" _generateMemctrlOptions "$1" _generateSpaceOptions "$1" + _generateCgroupOptions if test -n "$_IS_FAKEINIT"; then CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit ) @@ -1395,3 +1400,91 @@ function handleDeviceMap $_VDEVMAP --xid "$xid" "$op" "${vdevmap_opts[@]}" || return $? done } + +function hasCgroup +{ + $_GREP -q "cgroup" /proc/filesystems +} + +function _generateCgroupOptions +{ + local file + + hasCgroup || return 0 + + findFile file "$__CONFDIR/.defaults/cgroup/mnt" "" + if test -n "$file"; then + read CGROUP_MNT < "$file" + fi + findFile file "$__CONFDIR/.defaults/cgroup/subsys" "" + if test -n "$file"; then + read CGROUP_SUBSYS < "$file" + fi + findFile file "$__CONFDIR/.defaults/cgroup/inherit" "" + if test -n "$file"; then + _readFileToArray CGROUP_INHERIT "$file" "" + fi + + return 0 +} + +function useCgroup +{ + hasCgroup || return 1 + test -d "$CGROUP_MNT" || return 1 + test -d "$1/cgroup" -o \ + \( -d "$__CONFDIR/.defaults/cgroup" -a \ + ! -e "$1/nocgroup" \) +} + +function _handleCgroup +{ + local action="$1" + local vdir="$2" + local dir + local name + local i + local parent + + useCgroup "$vdir" || return 0 + + findDir dir "$vdir/cgroup" "$__CONFDIR/.defaults/cgroup" "" + test -d "$dir" || return 0 + + if test -r "$dir"/name; then + read name < "$dir"/name + else + read name < "$vdir"/name + fi + + if test "$action" = "attach"; then + if mkdir "$CGROUP_MNT/$name" 2>/dev/null; then + parent="$CGROUP_MNT/$name" + parent="${parent%/*}" + for i in "${CGROUP_INHERIT[@]}"; do + test -f "$parent/$i" || continue + cat "$parent/$i" > "$CGROUP_MNT/$name/$i" + done + + shopt -s nullglob + for i in "$dir"/*; do + cat "$i" > "$CGROUP_MNT/$name/${i##*/}" + done + fi + echo "$$" > "$CGROUP_MNT/$name/tasks" + elif test "$action" = "destroy"; then + rmdir "$CGROUP_MNT/$name" 2>/dev/null || : + fi + + return 0 +} + +function attachToCgroup +{ + _handleCgroup attach "$@" +} + +function destroyCgroup +{ + _handleCgroup destroy "$@" +} diff --git a/scripts/vserver.start b/scripts/vserver.start index 569c87e..cd3df9f 100644 --- a/scripts/vserver.start +++ b/scripts/vserver.start @@ -121,6 +121,7 @@ enableInterfaces "$VSERVER_DIR" && have_interfaces=1 mountVserver "$VSERVER_DIR" && is_mounted=1 prepareInit "$VSERVER_DIR" addtoCPUSET "$VSERVER_DIR" +attachToCgroup "$VSERVER_DIR" handleDeviceMap --set "$S_CONTEXT" "$VSERVER_DIR/apps/vdevmap" diff --git a/scripts/vserver.stop b/scripts/vserver.stop index 6c20260..033d0c3 100644 --- a/scripts/vserver.stop +++ b/scripts/vserver.stop @@ -126,3 +126,4 @@ saveDiskLimits "$VSERVER_DIR" execScriptlets "$VSERVER_DIR" "$VSERVER_NAME" postpost-stop removeCPUSET "$VSERVER_DIR" +destroyCgroup "$VSERVER_DIR" diff --git a/sysv/util-vserver b/sysv/util-vserver index 4374143..4f7f035 100755 --- a/sysv/util-vserver +++ b/sysv/util-vserver @@ -52,6 +52,14 @@ function create_dirs() $_MKDIR -p "$__RUNDIR" && $_MKDIR -p "$__VSHELPERSTATEDIR" && $_MKDIR -p `$_READLINK "$__PKGSTATEREVDIR"` } +function mount_cgroup() +{ + _generateCgroupOptions + test -n "$CGROUP_MNT" || return 0 + $_MKDIR -p "$CGROUP_MNT" + $_MOUNT -t cgroup -o "$CGROUP_SUBSYS" vserver "$CGROUP_MNT" +} + function start() { _beginResult $"Creating required directories" @@ -64,6 +72,11 @@ function start() _beginResult $"Loading default device map" handleDeviceMap --set 0 "$__CONFDIR/.defaults/apps/vdevmap" _endResult $? + if hasCgroup; then + _beginResult $"Mounting cgroup-hierarchy" + mount_cgroup + _endResult $? + fi test "$retval" -ne 0 || touch "$lockfile" return $retval } -- 1.8.1.5