diff options
author | Antoine Jacoutot <ajacoutot@cvs.openbsd.org> | 2021-11-06 10:38:05 +0000 |
---|---|---|
committer | Antoine Jacoutot <ajacoutot@cvs.openbsd.org> | 2021-11-06 10:38:05 +0000 |
commit | 737402941fe9d6337a09f8be46a607112f7020cf (patch) | |
tree | 6e1331ae3192aaec9877d8e0047e4494a352cf77 /etc/rc.d/rc.subr | |
parent | 05582389799ddd1358463bbbfb77b6f443f300f0 (diff) |
Allow passing a different signal than SIGTERM in the default rc_stop()
function. This will allow to simplify some rc.d script that cook there own
function to gracefully stop a process (e.g. web servers). There are other use
cases as well.
And do the same for rc_reload because it's cheap and can also simplify a
handful of rc.d scripts.
Behave like shutdown and if the process is still not down after daemon_timeout
(configurable; default to 30s), then send a SIGKILL.
While here, factorise pkill invocations into a _rc_sendsig() function that can
potentially be used by rc.d scripts instead of cooking pkill lines; this will
benefit from the configured routing table etc.
tested & ok robert@
Diffstat (limited to 'etc/rc.d/rc.subr')
-rw-r--r-- | etc/rc.d/rc.subr | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/etc/rc.d/rc.subr b/etc/rc.d/rc.subr index 0060ead2d6c..3845208a631 100644 --- a/etc/rc.d/rc.subr +++ b/etc/rc.d/rc.subr @@ -1,4 +1,4 @@ -# $OpenBSD: rc.subr,v 1.137 2021/10/31 17:46:23 ajacoutot Exp $ +# $OpenBSD: rc.subr,v 1.138 2021/11/06 10:38:04 ajacoutot Exp $ # # Copyright (c) 2010, 2011, 2014-2021 Antoine Jacoutot <ajacoutot@openbsd.org> # Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org> @@ -41,7 +41,8 @@ _rc_parse_conf() { local _l _rcfile _val set -A _allowed_keys -- \ accounting amd_master check_quotas ipsec library_aslr \ - multicast nfs_server pexp pf pkg_scripts shlib_dirs spamd_black + multicast nfs_server pexp pf pkg_scripts shlib_dirs \ + rc_reload_signal rc_stop_signal spamd_black [ $# -gt 0 ] || set -- /etc/rc.conf /etc/rc.conf.local for _rcfile; do @@ -120,6 +121,8 @@ daemon_rtable=${daemon_rtable} daemon_timeout=${daemon_timeout} daemon_user=${daemon_user} pexp=${pexp} +rc_reload_signal=${rc_reload_signal} +rc_stop_signal=${rc_stop_signal} EOF } @@ -141,6 +144,10 @@ _rc_alarm() kill $! 2>/dev/null # kill last job if it's running } +_rc_sendsig() { + pkill -${1:-TERM} -T "${daemon_rtable}" -xf "${pexp}" +} + _rc_wait() { local _i=0 if [ X"$1" = X"start" ]; then # prevent hanging the boot sequence @@ -160,6 +167,12 @@ _rc_wait() { reload) _rc_do rc_check && return 0 ;; stop) + # last chance: send a SIGTERM first in case the process + # used another signal to stop (e.g. SIGQUIT with nginx) + # or a non-default rc_stop() function; do it 2s before + # timeout to re-enter the loop one last time which will + # give 1s for SIGTERM to terminate the process + ((_i == daemon_timeout-2)) && _rc_do _rc_sendsig TERM _rc_do rc_check || return 0 ;; *) break ;; @@ -167,6 +180,10 @@ _rc_wait() { sleep 1 _i=$((_i+1)) done + if [ X"$1" = X"stop" ]; then # KILL the process + sleep 1 + _rc_do rc_check && _rc_do _rc_sendsig KILL + fi return 1 } @@ -180,11 +197,11 @@ rc_check() { } rc_reload() { - pkill -HUP -T "${daemon_rtable}" -xf "${pexp}" + _rc_sendsig ${rc_reload_signal} } rc_stop() { - pkill -T "${daemon_rtable}" -xf "${pexp}" + _rc_sendsig ${rc_stop_signal} } rc_cmd() { @@ -245,7 +262,7 @@ rc_cmd() { _rc_do rc_check || exit 0 echo $_n "${INRC:+ }${_name}" _rc_do rc_stop || _rc_exit failed - _rc_do _rc_wait stop || _rc_exit failed + _rc_do _rc_wait stop || _rc_exit killed if type rc_post >/dev/null; then _rc_do rc_post || _rc_exit failed fi @@ -289,6 +306,9 @@ _RC_RUNFILE=${_RC_RUNDIR}/${_name} # parse /etc/rc.conf{.local} for the daemon variables _rc_do _rc_parse_conf +rc_reload_signal=${rc_reload_signal:=HUP} +rc_stop_signal=${rc_stop_signal:=TERM} + eval _rcflags=\${${_name}_flags} eval _rclogger=\${${_name}_logger} eval _rcrtable=\${${_name}_rtable} |