rc: improve NAME_setup handling

Reload is used for service reconfiguration as well
and lacks a NAME_prepend-like mechanism so it makes
sense to extend the NAME_reload hook into this
action.

precmd may use configuration checks and blocks setup
from doing its designated work (e.g. nginx).  In moving
the invoke of the setup script in front allows us to
provide custom scripts for config file generation and
fixing prior to precmd checking configuration integrity.

Also introduce _run_rc_setup to separate the launcher
from the main one.  Let it run correctly in the case
of restart_precmd and block further execution as
would be the case in start due to the internal plumbing
of restart being split into calling stop and start
afterwards.

Differential-Revsiion: https://reviews.freebsd.org/D36259
Signed-off-by: Franco Fichtner <franco@opnsense.org>
Reviewed by: imp, oshogbo
Pull Request: https://github.com/freebsd/freebsd-src/pull/1258
This commit is contained in:
Franco Fichtner 2024-05-24 18:38:56 +02:00 committed by Warner Losh
parent b661d9e64d
commit 11333dd580
2 changed files with 58 additions and 28 deletions

View file

@ -975,7 +975,8 @@ startmsg()
# #
# ${name}_prepend n Command added before ${command}. # ${name}_prepend n Command added before ${command}.
# #
# ${name}_setup n Command executed before ${command}. # ${name}_setup n Command executed during start, restart and
# reload before ${rc_arg}_precmd is run.
# #
# ${name}_login_class n Login class to use, else "daemon". # ${name}_login_class n Login class to use, else "daemon".
# #
@ -1287,9 +1288,9 @@ run_rc_command()
return 1 return 1
fi fi
# if there's a custom ${XXX_cmd}, # if there's a custom ${XXX_cmd},
# run that instead of the default # run that instead of the default
# #
eval _cmd=\$${rc_arg}_cmd \ eval _cmd=\$${rc_arg}_cmd \
_precmd=\$${rc_arg}_precmd \ _precmd=\$${rc_arg}_precmd \
_postcmd=\$${rc_arg}_postcmd _postcmd=\$${rc_arg}_postcmd
@ -1301,6 +1302,14 @@ run_rc_command()
fi fi
if [ "${_rc_svcj}" != jailing ]; then if [ "${_rc_svcj}" != jailing ]; then
# service can redefine all so
# check for valid setup target
if [ "$rc_arg" = 'start' -o \
"$rc_arg" = 'restart' -o \
"$rc_arg" = 'reload' ]; then
_run_rc_setup || \
warn "failed to setup ${name}"
fi
_run_rc_precmd || return 1 _run_rc_precmd || return 1
fi fi
if ! checkyesno ${name}_svcj; then if ! checkyesno ${name}_svcj; then
@ -1400,6 +1409,8 @@ run_rc_command()
fi fi
if [ "${_rc_svcj}" != jailing ]; then if [ "${_rc_svcj}" != jailing ]; then
_run_rc_setup || warn "failed to setup ${name}"
if ! _run_rc_precmd; then if ! _run_rc_precmd; then
warn "failed precmd routine for ${name}" warn "failed precmd routine for ${name}"
return 1 return 1
@ -1416,8 +1427,8 @@ run_rc_command()
fi fi
fi fi
# setup the full command to run # setup the full command to run
# #
startmsg "Starting ${name}." startmsg "Starting ${name}."
if [ -n "$_chroot" ]; then if [ -n "$_chroot" ]; then
_cd= _cd=
@ -1448,16 +1459,9 @@ $_cpusetcmd $command $rc_flags $command_args"
fi fi
fi fi
if [ -n "$_setup" ]; then # Prepend default limits
if ! _run_rc_doit "$_setup"; then
warn "failed to setup ${name}"
fi
fi
# Prepend default limits
_doit="$_cd limits -C $_login_class $_limits $_doit" _doit="$_cd limits -C $_login_class $_limits $_doit"
local _really_run_it=true local _really_run_it=true
if checkyesno ${name}_svcj; then if checkyesno ${name}_svcj; then
if [ "${_rc_svcj}" != jailing ]; then if [ "${_rc_svcj}" != jailing ]; then
@ -1466,8 +1470,8 @@ $_cpusetcmd $command $rc_flags $command_args"
fi fi
if [ "$_really_run_it" = true ]; then if [ "$_really_run_it" = true ]; then
# run the full command # run the full command
# #
if ! _run_rc_doit "$_doit"; then if ! _run_rc_doit "$_doit"; then
warn "failed to start ${name}" warn "failed to start ${name}"
return 1 return 1
@ -1475,8 +1479,8 @@ $_cpusetcmd $command $rc_flags $command_args"
fi fi
if [ "${_rc_svcj}" != jailing ]; then if [ "${_rc_svcj}" != jailing ]; then
# finally, run postcmd # finally, run postcmd
# #
_run_rc_postcmd _run_rc_postcmd
fi fi
;; ;;
@ -1490,14 +1494,14 @@ $_cpusetcmd $command $rc_flags $command_args"
_run_rc_precmd || return 1 _run_rc_precmd || return 1
# send the signal to stop # send the signal to stop
# #
echo "Stopping ${name}." echo "Stopping ${name}."
_doit=$(_run_rc_killcmd "${sig_stop:-TERM}") _doit=$(_run_rc_killcmd "${sig_stop:-TERM}")
_run_rc_doit "$_doit" || return 1 _run_rc_doit "$_doit" || return 1
# wait for the command to exit, # wait for the command to exit,
# and run postcmd. # and run postcmd.
wait_for_pids $rc_pid wait_for_pids $rc_pid
if checkyesno ${name}_svcj; then if checkyesno ${name}_svcj; then
@ -1514,6 +1518,8 @@ $_cpusetcmd $command $rc_flags $command_args"
return 1 return 1
fi fi
_run_rc_setup || warn "failed to setup ${name}"
_run_rc_precmd || return 1 _run_rc_precmd || return 1
_doit=$(_run_rc_killcmd "${sig_reload:-HUP}") _doit=$(_run_rc_killcmd "${sig_reload:-HUP}")
@ -1523,9 +1529,11 @@ $_cpusetcmd $command $rc_flags $command_args"
;; ;;
restart) restart)
# prevent restart being called more _run_rc_setup || warn "failed to setup ${name}"
# than once by any given script
# # prevent restart being called more
# than once by any given script
#
if ${_rc_restart_done:-false}; then if ${_rc_restart_done:-false}; then
return 0 return 0
fi fi
@ -1638,6 +1646,7 @@ $_cpusetcmd $command $rc_flags $command_args"
# _precmd R # _precmd R
# _postcmd R # _postcmd R
# _return W # _return W
# _setup R
# #
_run_rc_precmd() _run_rc_precmd()
{ {
@ -1669,6 +1678,20 @@ _run_rc_postcmd()
return 0 return 0
} }
_run_rc_setup()
{
# prevent multiple execution on restart => stop/start split
if ! ${_rc_restart_done:-false} && [ -n "$_setup" ]; then
debug "run_rc_command: ${rc_arg}_setup: $_setup"
eval "$_setup"
_return=$?
if [ $_return -ne 0 ]; then
return 1
fi
fi
return 0
}
_run_rc_doit() _run_rc_doit()
{ {
local _m local _m

View file

@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd February 10, 2024 .Dd May 28, 2024
.Dt RC.SUBR 8 .Dt RC.SUBR 8
.Os .Os
.Sh NAME .Sh NAME
@ -826,8 +826,15 @@ This is a generic version of
or or
.Va ${name}_nice . .Va ${name}_nice .
.It Va ${name}_setup .It Va ${name}_setup
Command to be run prior to Optional command to be run during
.Va command . .Cm start ,
.Cm restart ,
and
.Cm reload
prior to the respective
.Ar argument Ns Va _precmd .
If the command fails for any reason it will output a warning,
but execution will continue.
.It Ar argument Ns Va _cmd .It Ar argument Ns Va _cmd
Shell commands which override the default method for Shell commands which override the default method for
.Ar argument . .Ar argument .