add cgroup cleanup support

This adds the ability to kill all processes within a service's cgroup
when that service is stopped or restarted.
This commit is contained in:
Alexander Vershilov 2013-04-16 09:52:33 +04:00 committed by William Hubbs
parent e4668a5061
commit c984506537
3 changed files with 47 additions and 0 deletions

View File

@ -66,3 +66,13 @@ rc_tty_number=12
# Set the net_prio controller settings for this service. # Set the net_prio controller settings for this service.
#rc_cgroup_net_prio="" #rc_cgroup_net_prio=""
# Set this to YES if yu want all of the processes in a service's cgroup
# killed when the service is stopped or restarted.
# This should not be set globally because it kills all of the service's
# child processes, and most of the time this is undesirable. Please set
# it in /etc/conf.d/<service>.
# To perform this cleanup manually for a stopped service, you can
# execute cgroup_cleanup with /etc/init.d/<service> cgroup_cleanup or
# rc-service <service> cgroup_cleanup.
# rc_cgroup_cleanup="NO"

View File

@ -1,6 +1,7 @@
#!@SHELL@ #!@SHELL@
# Copyright (c) 2012 Alexander Vershilov <qnikst@gentoo.org> # Copyright (c) 2012 Alexander Vershilov <qnikst@gentoo.org>
# Released under the 2-clause BSD license. # Released under the 2-clause BSD license.
extra_stopped_commands="${extra_stopped_commands} cgroup_cleanup"
cgroup_find_path() cgroup_find_path()
{ {
@ -15,6 +16,21 @@ cgroup_find_path()
echo $result echo $result
} }
cgroup_get_pids()
{
local p
pids=
while read p; do
[ $p -eq $$ ] || $pids="${pids} ${p}"
done < /sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks
[ -n "$pids" ]
}
cgroup_running()
{
[ -d "/sys/fs/cgroup/openrc/${RC_SVCNAME}" ]
}
cgroup_set_values() cgroup_set_values()
{ {
[ -n "$1" -a -n "$2" -a -d "/sys/fs/cgroup/$1" ] || return 0 [ -n "$1" -a -n "$2" -a -d "/sys/fs/cgroup/$1" ] || return 0
@ -86,3 +102,22 @@ cgroup_set_limits()
return 0 return 0
} }
cgroup_cleanup()
{
yesno "${rc_cgroup_cleanup:-no}" && 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
done
cgroup_get_pids || { eend 0 "finished" ; return 0; }
kill -9 $pids
eend $(cgroup_running && echo 1 || echo 0) "fail to stop all processes"
}

View File

@ -302,6 +302,8 @@ while [ -n "$1" ]; do
then then
"$1"_post || exit $? "$1"_post || exit $?
fi fi
[ "$(command -v cgroup_cleanup)" = "cgroup_cleanup" ] && \
cgroup_cleanup
shift shift
continue 2 continue 2
else else