rc-cgroup.sh: avoid process substitution for cgroup_get_pids

This should make cgroup_cleanup work successfully since cgroup_get_pids
no longer uses a subshell.

This fixes #396.
This fixes #397.
This commit is contained in:
William Hubbs 2021-02-24 18:05:00 -06:00
parent 4fb4674374
commit de77674663

View File

@ -24,18 +24,26 @@ cgroup_find_path()
printf "%s" "${result}" printf "%s" "${result}"
} }
# This extracts all pids in a cgroup and puts them in the cgroup_pids
# variable.
# It is done this way to avoid subshells so we don't have to worry about
# locating the pid of the subshell in the cgroup.
# https://github.com/openrc/openrc/issues/396
cgroup_get_pids() cgroup_get_pids()
{ {
local cgroup_procs p pids local cgroup_procs p
cgroup_pids=
cgroup_procs="$(cgroup2_find_path)" cgroup_procs="$(cgroup2_find_path)"
[ -n "${cgroup_procs}" ] && if [ -n "${cgroup_procs}" ]; then
cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs" || cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs"
else
cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks" cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks"
fi
[ -f "${cgroup_procs}" ] || return 0 [ -f "${cgroup_procs}" ] || return 0
while read -r p; do while read -r p; do
[ "$p" -eq $$ ] || pids="${pids} ${p}" [ "$p" -eq $$ ] && continue
cgroup_pids="${cgroup_pids} ${p}"
done < "${cgroup_procs}" done < "${cgroup_procs}"
printf "%s" "${pids}"
return 0 return 0
} }
@ -201,25 +209,28 @@ cgroup_cleanup()
{ {
cgroup_running || return 0 cgroup_running || return 0
ebegin "starting cgroups cleanup" ebegin "starting cgroups cleanup"
local pids loops=0 local loops=0
pids="$(cgroup_get_pids)" cgroup_get_pids
if [ -n "${pids}" ]; then if [ -n "${cgroup_pids}" ]; then
kill -s CONT ${pids} 2> /dev/null kill -s CONT ${cgroup_pids} 2> /dev/null
kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null kill -s "${stopsig:-TERM}" ${cgroup_pids} 2> /dev/null
yesno "${rc_send_sighup:-no}" && yesno "${rc_send_sighup:-no}" &&
kill -s HUP ${pids} 2> /dev/null kill -s HUP ${cgroup_pids} 2> /dev/null
kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null kill -s "${stopsig:-TERM}" ${cgroup_pids} 2> /dev/null
while [ -n "$(cgroup_get_pids)" ] && cgroup_get_pids
while [ -n "$(cgroup_pids)" ] &&
[ "${loops}" -lt "${rc_timeout_stopsec:-90}" ]; do [ "${loops}" -lt "${rc_timeout_stopsec:-90}" ]; do
loops=$((loops+1)) loops=$((loops+1))
sleep 1 sleep 1
cgroup_get_pids
done done
pids="$(cgroup_get_pids)" if [ -n "${cgroup_pids}" ] && yesno "${rc_send_sigkill:-yes}"; then
[ -n "${pids}" ] && yesno "${rc_send_sigkill:-yes}" && kill -s KILL ${cgroup_pids} 2> /dev/null
kill -s KILL ${pids} 2> /dev/null fi
fi fi
cgroup2_remove cgroup2_remove
[ -z "$(cgroup_get_pids)" ] cgroup_get_pids
[ -z "${cgroup_pids}" ]
eend $? "Unable to stop all processes" eend $? "Unable to stop all processes"
return 0 return 0
} }