aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 4fb48ae9..79bd9713 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 449c1d37..c057fc8a 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 c9a37454..dcddd9b1 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