--- sh/rc-cgroup.sh.in 2015-03-14 12:22:38.715942582 +0100 +++ sh/rc-cgroup.sh.in 2015-03-18 10:23:33.819998208 +0100 @@ -1,56 +1,59 @@ -#!@SHELL@ +#!@SHELL@ # Copyright (c) 2012 Alexander Vershilov # Released under the 2-clause BSD license. extra_stopped_commands="${extra_stopped_commands} cgroup_cleanup" description_cgroup_cleanup="Kill all processes in the cgroup" +CG_NAME="openrc" +CG_ROOT="/sys/fs/cgroup" +CG_PATH="$CG_ROOT/$CG_NAME" + cgroup_find_path() { - local OIFS n name dir result + local ifs name dir DIR [ -n "$1" ] || return 0 - OIFS="$IFS" - IFS=":" + ifs="$IFS" FS=":" while read n name dir; do - [ "$name" = "$1" ] && result="$dir" + [ "$name" = "$1" ] && DIR="$dir" done < /proc/1/cgroup - IFS="$OIFS" - echo $result + IFS="$ifs" + echo "$DIR" } cgroup_get_pids() { local p - pids= + PIDS= while read p; do - [ $p -eq $$ ] || pids="${pids} ${p}" - done < /sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks - [ -n "$pids" ] + [ $p -eq $$ ] || PIDS="$PIDS $p" + done < $CG_PATH/$RC_SVCNAME/tasks + [ -n "$PIDS" ] } -cgroup_running() +cgroup_get_state() { - [ -d "/sys/fs/cgroup/openrc/${RC_SVCNAME}" ] + [ -d "$CG_PATH/$RC_SVCNAME" ] } cgroup_set_values() { - [ -n "$1" -a -n "$2" -a -d "/sys/fs/cgroup/$1" ] || return 0 + [ -n "$1" -a -n "$2" -a -d "$CG_ROOT/$1" ] || return 0 - local controller="$1" h=$(cgroup_find_path "$1") - cgroup="/sys/fs/cgroup/${1}${h}openrc_${RC_SVCNAME}" - [ -d "$cgroup" ] || mkdir -p "$cgroup" + local ctrl group head + ctrl="$1" head=$(cgroup_find_path "$1") + group="$CG_ROOT/${1}${head}${CG_NAME}_$RC_SVCNAME" + [ -d "$group" ] || mkdir -p "$group" set -- $2 local name val - while [ -n "$1" -a "$controller" != "cpuacct" ]; do + while [ -n "$1" -a "$ctrl" != "cpuacct" ]; do case "$1" in - $controller.*) - if [ -n "$name" -a -f "$cgroup/$name" -a -n "$val" ]; then - veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val" - echo $val > "$cgroup/$name" + $ctrl.*) + if [ -n "$name" -a -f "$group/$name" -a -n "$val" ]; then + veinfo "$RC_SVCNAME: Setting $group/$name to $val" + echo "$val" > "$group/$name" fi - name=$1 - val= + name=$1 val= ;; *) val="$val $1" @@ -58,79 +61,60 @@ esac shift done - if [ -n "$name" -a -f "$cgroup/$name" -a -n "$val" ]; then - veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val" - echo $val > "$cgroup/$name" + if [ -n "$name" -a -f "$group/$name" -a -n "$val" ]; then + veinfo "$RC_SVCNAME: Setting $group/$name to $val" + echo "$val" > "$group/$name" fi - - if [ -f "$cgroup/tasks" ]; then - veinfo "$RC_SVCNAME: adding to $cgroup/tasks" - echo 0 > "$cgroup/tasks" + if [ -f "$group/tasks" ]; then + veinfo "$RC_SVCNAME: Adding to $group/tasks" + echo $$ > "$group/tasks" fi - return 0 } cgroup_add_service() { - # relocate starting process to the top of the cgroup - # it prevents from unwanted inheriting of the user - # cgroups. But may lead to a problems where that inheriting - # is needed. - for d in /sys/fs/cgroup/* ; do - [ -f "${d}"/tasks ] && echo 0 > "${d}"/tasks - done - - openrc_cgroup=/sys/fs/cgroup/openrc - if [ -d "$openrc_cgroup" ]; then - cgroup="$openrc_cgroup/$RC_SVCNAME" - mkdir -p "$cgroup" - [ -f "$cgroup/tasks" ] && echo 0 > "$cgroup/tasks" + # FIXME: + # Relocating process to the top of the CGroup to prevent + # unwanted inheriting user CGroup may lead to issue when + # inheriting may be necessary. + if yesno ${rc_cgroup_inherit:-${RC_CGROUP_INHERIT:-Yes}}; then + local dir + for dir in $CG_ROOT/*; do + [ -f "$dir"/tasks ] && echo $$ > "$dir"/tasks + done + fi + if [ -d "$CG_PATH" ]; then + local group + group="$CG_PATH/$RC_SVCNAME" + mkdir -p "$group" + [ -f "$group/tasks" ] && echo $$ > "$group/tasks" fi } cgroup_set_limits() { - local blkio="${rc_cgroup_blkio:-$RC_CGROUP_BLKIO}" - [ -n "$blkio" ] && cgroup_set_values blkio "$blkio" - - local cpu="${rc_cgroup_cpu:-$RC_CGROUP_CPU}" - [ -n "$cpu" ] && cgroup_set_values cpu "$cpu" - - local cpuacct="${rc_cgroup_cpuacct:-$RC_CGROUP_CPUACCT}" - [ -n "$cpuacct" ] && cgroup_set_values cpuacct "$cpuacct" - - local cpuset="${rc_cgroup_cpuset:-$RC_CGROUP_cpuset}" - [ -n "$cpuset" ] && cgroup_set_values cpuset "$cpuset" - - local devices="${rc_cgroup_devices:-$RC_CGROUP_DEVICES}" - [ -n "$devices" ] && cgroup_set_values devices "$devices" - - local memory="${rc_cgroup_memory:-$RC_CGROUP_MEMORY}" - [ -n "$memory" ] && cgroup_set_values memory "$memory" - - local net_prio="${rc_cgroup_net_prio:-$RC_CGROUP_NET_PRIO}" - [ -n "$net_prio" ] && cgroup_set_values net_prio "$net_prio" + local ctrl blkio cpu cpuacct cpuset devices memory net_prio + for ctrl in blkio:BLKIO cpu:CPU cpuacct:CPUACCT cpuset:CPUSET \ + devices:DEVICES memory:MEMORY net_prio:NET_PRIO; do + eval ${ctrl%:*}=\"\${rc_cgroup_${ctrl%:*}:-\$RC_CGROUP_${ctrl#*:}}\" + eval test -n \"\$${ctrl%:*}\" && cgroup_set_values "${ctrl%:*}" "\$${ctrl%:*}" + done return 0 } cgroup_cleanup() { - cgroup_running || return 0 - ebegin "starting cgroups cleanup" - for sig in TERM QUIT INT; do - cgroup_get_pids || { eend 0 "finished" ; return 0 ; } - for i in 0 1; do - kill -s $sig $pids - for j in 0 1 2; do - cgroup_get_pids || { eend 0 "finished" ; return 0 ; } - sleep 1 - done - done 2>/dev/null + cgroup_get_state || return 0 + local CGROUP_GET_PIDS SIG + CGROUP_GET_PIDS='cgroup_get_pids || { eend 0; return 0; };' + + ebegin "Cleaning up CGroup" + for SIG in TERM QUIT INT; do + eval $CGROUP_GET_PIDS + kill -$SIG $PIDS done - cgroup_get_pids || { eend 0 "finished" ; return 0; } - kill -9 $pids - eend $(cgroup_running && echo 1 || echo 0) "fail to stop all processes" + eval $CGROUP_GET_PIDS + kill -TERM $PIDS } -