summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Vershilov <alexander.vershilov@gmail.com>2013-04-16 09:52:33 +0400
committerWilliam Hubbs <w.d.hubbs@gmail.com>2013-04-25 16:59:19 -0500
commitc984506537fbb8a3adefd2d57dd4dc831eeb79c3 (patch)
tree8921f1c4bb8d08cb428d0fc106b75986c2eae92b
parente4668a5061de4f225d4e9d534ff6212e634e45d2 (diff)
downloadopenrc-c984506537fbb8a3adefd2d57dd4dc831eeb79c3.tar.gz
openrc-c984506537fbb8a3adefd2d57dd4dc831eeb79c3.tar.bz2
openrc-c984506537fbb8a3adefd2d57dd4dc831eeb79c3.tar.xz
add cgroup cleanup support
This adds the ability to kill all processes within a service's cgroup when that service is stopped or restarted.
-rw-r--r--etc/rc.conf.Linux10
-rw-r--r--sh/rc-cgroup.sh.in35
-rw-r--r--sh/runscript.sh.in2
3 files changed, 47 insertions, 0 deletions
diff --git a/etc/rc.conf.Linux b/etc/rc.conf.Linux
index 4fb48ae..79bd971 100644
--- a/etc/rc.conf.Linux
+++ b/etc/rc.conf.Linux
@@ -66,3 +66,13 @@ rc_tty_number=12
# Set the net_prio controller settings for this service.
#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"
diff --git a/sh/rc-cgroup.sh.in b/sh/rc-cgroup.sh.in
index 449c1d3..c057fc8 100644
--- a/sh/rc-cgroup.sh.in
+++ b/sh/rc-cgroup.sh.in
@@ -1,6 +1,7 @@
#!@SHELL@
# Copyright (c) 2012 Alexander Vershilov <qnikst@gentoo.org>
# Released under the 2-clause BSD license.
+extra_stopped_commands="${extra_stopped_commands} cgroup_cleanup"
cgroup_find_path()
{
@@ -15,6 +16,21 @@ cgroup_find_path()
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()
{
[ -n "$1" -a -n "$2" -a -d "/sys/fs/cgroup/$1" ] || return 0
@@ -86,3 +102,22 @@ cgroup_set_limits()
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"
+}
diff --git a/sh/runscript.sh.in b/sh/runscript.sh.in
index c9a3745..dcddd9b 100644
--- a/sh/runscript.sh.in
+++ b/sh/runscript.sh.in
@@ -302,6 +302,8 @@ while [ -n "$1" ]; do
then
"$1"_post || exit $?
fi
+ [ "$(command -v cgroup_cleanup)" = "cgroup_cleanup" ] && \
+ cgroup_cleanup
shift
continue 2
else