Make cgroup_cleanup send only one sigterm and sigkill

Instead of looping and sending multiple signals to child processes in
cgroup_cleanup, we send sigterm followed by sleeping one second then
sigkill.

This brings us more in line with systemd's "control group" killmode
setting.

Also, this commit includes several shellcheck cleanups.
This commit is contained in:
William Hubbs 2017-09-14 10:55:06 -05:00
parent 8885580986
commit 2b0345165e
2 changed files with 43 additions and 35 deletions

View File

@ -365,9 +365,9 @@ while [ -n "$1" ]; do
then then
"$1"_post || exit $? "$1"_post || exit $?
fi fi
[ "$(command -v cgroup_cleanup)" = "cgroup_cleanup" -a \ [ "$(command -v cgroup_cleanup)" = "cgroup_cleanup" ] &&
"$1" = "stop" ] && \ [ "$1" = "stop" ] &&
yesno "${rc_cgroup_cleanup}" && \ yesno "${rc_cgroup_cleanup}" && \
cgroup_cleanup cgroup_cleanup
if [ "$(command -v cgroup2_remove)" = "cgroup2_remove" ]; then if [ "$(command -v cgroup2_remove)" = "cgroup2_remove" ]; then
[ "$1" = stop ] || [ -z "${command}" ] && [ "$1" = stop ] || [ -z "${command}" ] &&

View File

@ -14,46 +14,56 @@ description_cgroup_cleanup="Kill all processes in the cgroup"
cgroup_find_path() cgroup_find_path()
{ {
local OIFS n name dir result local OIFS name dir result
[ -n "$1" ] || return 0 [ -n "$1" ] || return 0
OIFS="$IFS" OIFS="$IFS"
IFS=":" IFS=":"
while read n name dir; do while read -r _ name dir; do
[ "$name" = "$1" ] && result="$dir" [ "$name" = "$1" ] && result="$dir"
done < /proc/1/cgroup done < /proc/1/cgroup
IFS="$OIFS" IFS="$OIFS"
echo $result printf "%s" "${result}"
} }
cgroup_get_pids() cgroup_get_pids()
{ {
local p local cgroup_procs p pids
pids= cgroup_procs="$(cgroup2_find_path)"
while read p; do [ -n "${cgroup_procs}" ] &&
[ $p -eq $$ ] || pids="${pids} ${p}" cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs" ||
done < /sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks"
[ -n "$pids" ] [ -f "${cgroup_procs}" ] || return 0
while read -r p; do
[ "$p" -eq $$ ] || pids="${pids} ${p}"
done < "${cgroup_procs}"
printf "%s" "${pids}"
return 0
} }
cgroup_running() cgroup_running()
{ {
[ -d "/sys/fs/cgroup/openrc/${RC_SVCNAME}" ] [ -d "/sys/fs/cgroup/unified/${RC_SVCNAME}" ] ||
[ -d "/sys/fs/cgroup/${RC_SVCNAME}" ] ||
[ -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" ] && [ -n "$2" ] && [ -d "/sys/fs/cgroup/$1" ] || return 0
local controller="$1" h=$(cgroup_find_path "$1") local controller h
controller="$1"
h=$(cgroup_find_path "$1")
cgroup="/sys/fs/cgroup/${1}${h}openrc_${RC_SVCNAME}" cgroup="/sys/fs/cgroup/${1}${h}openrc_${RC_SVCNAME}"
[ -d "$cgroup" ] || mkdir -p "$cgroup" [ -d "$cgroup" ] || mkdir -p "$cgroup"
set -- $2 set -- $2
local name val local name val
while [ -n "$1" -a "$controller" != "cpuacct" ]; do while [ -n "$1" ] && [ "$controller" != "cpuacct" ]; do
case "$1" in case "$1" in
$controller.*) $controller.*)
if [ -n "$name" -a -w "$cgroup/$name" -a -n "$val" ]; then if [ -n "${name}" ] && [ -w "${cgroup}/${name}" ] &&
[ -n "${val}" ]; then
veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val" veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val"
printf "%s" "$val" > "$cgroup/$name" printf "%s" "$val" > "$cgroup/$name"
fi fi
@ -68,7 +78,7 @@ cgroup_set_values()
esac esac
shift shift
done done
if [ -n "$name" -a -w "$cgroup/$name" -a -n "$val" ]; then if [ -n "${name}" ] && [ -w "${cgroup}/${name}" ] && [ -n "${val}" ]; then
veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val" veinfo "$RC_SVCNAME: Setting $cgroup/$name to $val"
printf "%s" "$val" > "$cgroup/$name" printf "%s" "$val" > "$cgroup/$name"
fi fi
@ -145,7 +155,8 @@ cgroup2_find_path()
cgroup2_remove() cgroup2_remove()
{ {
local cgroup_path="$(cgroup2_find_path)" rc_cgroup_path local cgroup_path rc_cgroup_path
cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0 [ -z "${cgroup_path}" ] && return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
[ ! -d "${rc_cgroup_path}" ] || [ ! -d "${rc_cgroup_path}" ] ||
@ -154,7 +165,7 @@ cgroup2_remove()
grep -qx "$$" "${rc_cgroup_path}/cgroup.procs" && grep -qx "$$" "${rc_cgroup_path}/cgroup.procs" &&
echo 0 > "${cgroup_path}/cgroup.procs" echo 0 > "${cgroup_path}/cgroup.procs"
local key populated vvalue local key populated vvalue
while read key value; do while read -r key value; do
case "${key}" in case "${key}" in
populated) populated=${value} ;; populated) populated=${value} ;;
*) ;; *) ;;
@ -167,7 +178,8 @@ cgroup2_remove()
cgroup2_set_limits() cgroup2_set_limits()
{ {
local cgroup_path="$(cgroup2_find_path)" local cgroup_path
cgroup_path="$(cgroup2_find_path)"
[ -z "${cgroup_path}" ] && return 0 [ -z "${cgroup_path}" ] && return 0
rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}" rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
local OIFS="$IFS" local OIFS="$IFS"
@ -175,7 +187,7 @@ cgroup2_set_limits()
" "
[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}" [ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
echo 0 > "${rc_cgroup_path}/cgroup.procs" echo 0 > "${rc_cgroup_path}/cgroup.procs"
echo "${rc_cgroup_settings}" | while IFS="$OIFS" read key value; do echo "${rc_cgroup_settings}" | while IFS="$OIFS" read -r key value; do
[ -z "${key}" ] || [ -z "${value}" ] && continue [ -z "${key}" ] || [ -z "${value}" ] && continue
[ ! -e "${rc_cgroup_path}/${key}" ] && continue [ ! -e "${rc_cgroup_path}/${key}" ] && continue
veinfo "${RC_SVCNAME}: cgroups: ${key} ${value}" veinfo "${RC_SVCNAME}: cgroups: ${key} ${value}"
@ -189,17 +201,13 @@ cgroup_cleanup()
{ {
cgroup_running || return 0 cgroup_running || return 0
ebegin "starting cgroups cleanup" ebegin "starting cgroups cleanup"
for sig in TERM QUIT INT; do local pids
cgroup_get_pids || { eend 0 "finished" ; return 0 ; } pids="$(cgroup_get_pids)"
for i in 0 1; do if [ -n "${pids}" ]; then
kill -s $sig $pids kill -s TERM "${pids}"
for j in 0 1 2; do sleep 1
cgroup_get_pids || { eend 0 "finished" ; return 0 ; } pids="$(cgroup_get_pids)"
sleep 1 [ -n "${pids}" ] &&
done kill -s KILL "${pids}"
done 2>/dev/null fi
done
cgroup_get_pids || { eend 0 "finished" ; return 0; }
kill -9 $pids
eend $(cgroup_running && echo 1 || echo 0) "fail to stop all processes"
} }