git: 11333dd580b7 - main - rc: improve NAME_setup handling

From: Warner Losh <imp_at_FreeBSD.org>
Date: Wed, 29 May 2024 17:28:25 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=11333dd580b704fb4ff0836e1d1a0634099b0cf6

commit 11333dd580b704fb4ff0836e1d1a0634099b0cf6
Author:     Franco Fichtner <franco@opnsense.org>
AuthorDate: 2024-05-24 16:38:56 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-05-29 17:23:46 +0000

    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
---
 libexec/rc/rc.subr       | 73 +++++++++++++++++++++++++++++++-----------------
 share/man/man8/rc.subr.8 | 13 +++++++--
 2 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr
index 23651cbf8e58..1b0fdc837228 100644
--- a/libexec/rc/rc.subr
+++ b/libexec/rc/rc.subr
@@ -975,7 +975,8 @@ startmsg()
 #
 #	${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".
 #
@@ -1287,9 +1288,9 @@ run_rc_command()
 			return 1
 		fi
 
-					# if there's a custom ${XXX_cmd},
-					# run that instead of the default
-					#
+		# if there's a custom ${XXX_cmd},
+		# run that instead of the default
+		#
 		eval _cmd=\$${rc_arg}_cmd \
 		     _precmd=\$${rc_arg}_precmd \
 		     _postcmd=\$${rc_arg}_postcmd
@@ -1301,6 +1302,14 @@ run_rc_command()
 			fi
 
 			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
 			fi
 			if ! checkyesno ${name}_svcj; then
@@ -1400,6 +1409,8 @@ run_rc_command()
 			fi
 
 			if [ "${_rc_svcj}" != jailing ]; then
+				_run_rc_setup || warn "failed to setup ${name}"
+
 				if ! _run_rc_precmd; then
 					warn "failed precmd routine for ${name}"
 					return 1
@@ -1416,8 +1427,8 @@ run_rc_command()
 				fi
 			fi
 
-					# setup the full command to run
-					#
+			# setup the full command to run
+			#
 			startmsg "Starting ${name}."
 			if [ -n "$_chroot" ]; then
 				_cd=
@@ -1448,16 +1459,9 @@ $_cpusetcmd $command $rc_flags $command_args"
 				fi
 			fi
 
-			if [ -n "$_setup" ]; then
-				if ! _run_rc_doit "$_setup"; then
-					warn "failed to setup ${name}"
-				fi
-			fi
-
-					# Prepend default limits
+			# Prepend default limits
 			_doit="$_cd limits -C $_login_class $_limits $_doit"
 
-
 			local _really_run_it=true
 			if checkyesno ${name}_svcj; then
 				if [ "${_rc_svcj}" != jailing ]; then
@@ -1466,8 +1470,8 @@ $_cpusetcmd $command $rc_flags $command_args"
 			fi
 
 			if [ "$_really_run_it" = true ]; then
-					# run the full command
-					#
+				# run the full command
+				#
 				if ! _run_rc_doit "$_doit"; then
 					warn "failed to start ${name}"
 					return 1
@@ -1475,8 +1479,8 @@ $_cpusetcmd $command $rc_flags $command_args"
 			fi
 
 			if [ "${_rc_svcj}" != jailing ]; then
-					# finally, run postcmd
-					#
+				# finally, run postcmd
+				#
 				_run_rc_postcmd
 			fi
 			;;
@@ -1490,14 +1494,14 @@ $_cpusetcmd $command $rc_flags $command_args"
 
 			_run_rc_precmd || return 1
 
-					# send the signal to stop
-					#
+			# send the signal to stop
+			#
 			echo "Stopping ${name}."
 			_doit=$(_run_rc_killcmd "${sig_stop:-TERM}")
 			_run_rc_doit "$_doit" || return 1
 
-					# wait for the command to exit,
-					# and run postcmd.
+			# wait for the command to exit,
+			# and run postcmd.
 			wait_for_pids $rc_pid
 
 			if checkyesno ${name}_svcj; then
@@ -1514,6 +1518,8 @@ $_cpusetcmd $command $rc_flags $command_args"
 				return 1
 			fi
 
+			_run_rc_setup || warn "failed to setup ${name}"
+
 			_run_rc_precmd || return 1
 
 			_doit=$(_run_rc_killcmd "${sig_reload:-HUP}")
@@ -1523,9 +1529,11 @@ $_cpusetcmd $command $rc_flags $command_args"
 			;;
 
 		restart)
-					# prevent restart being called more
-					# than once by any given script
-					#
+			_run_rc_setup || warn "failed to setup ${name}"
+
+			# prevent restart being called more
+			# than once by any given script
+			#
 			if ${_rc_restart_done:-false}; then
 				return 0
 			fi
@@ -1638,6 +1646,7 @@ $_cpusetcmd $command $rc_flags $command_args"
 #	_precmd		R
 #	_postcmd	R
 #	_return		W
+#	_setup		R
 #
 _run_rc_precmd()
 {
@@ -1669,6 +1678,20 @@ _run_rc_postcmd()
 	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()
 {
 	local _m
diff --git a/share/man/man8/rc.subr.8 b/share/man/man8/rc.subr.8
index 0906ecb2e787..8f7b72e96dc5 100644
--- a/share/man/man8/rc.subr.8
+++ b/share/man/man8/rc.subr.8
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 10, 2024
+.Dd May 28, 2024
 .Dt RC.SUBR 8
 .Os
 .Sh NAME
@@ -826,8 +826,15 @@ This is a generic version of
 or
 .Va ${name}_nice .
 .It Va ${name}_setup
-Command to be run prior to
-.Va command .
+Optional command to be run during
+.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
 Shell commands which override the default method for
 .Ar argument .