Bug#1108969: sysvinit-utils: add common support for oneshot services in init-d-script helper

Mark Hindley mark at hindley.org.uk
Tue Sep 9 17:30:56 BST 2025


If the diff is easier, see below. But I have whitespace changes which might make
it a fiddly merge.

Mark

diff --git a/debian/init-d-script b/debian/init-d-script
index 31ded62f..bd4f2b04 100755
--- a/debian/init-d-script
+++ b/debian/init-d-script
@@ -39,6 +39,29 @@ call() {
 	fi
 }
 
+#
+# Support for oneshot services
+#
+oneshot() {
+	[ "$TYPE" = oneshot ] || return
+	IDS_RUNDIR=/run/init-d-script
+	case $1 in
+		setup) mkdir -p "$IDS_RUNDIR" ;;
+		start-pre) [ -f /$IDS_RUNDIR/$NAME.oneshot ] && exit ;;
+		start-post) touch /$IDS_RUNDIR/$NAME.oneshot ;;
+		stop-pre) [ -f /$IDS_RUNDIR/$NAME.oneshot ] || exit ;;
+		stop-post) rm -f /$IDS_RUNDIR/$NAME.oneshot ;;
+		status)
+			if [ -f /$IDS_RUNDIR/$NAME.oneshot ]; then
+				log_success_msg "$NAME (oneshot) has been run"
+			else
+				log_failure_msg "$NAME (oneshot) has not been run"
+			fi
+			;;
+		*) echo "ERROR: invalid oneshot request: $1" >&2 ;;
+	esac
+}
+
 #
 # Function that starts the daemon/service
 #
@@ -56,18 +79,21 @@ do_start_cmd() {
 		${DAEMON:+--exec "$DAEMON"} $START_ARGS -- $DAEMON_ARGS
 }
 
-do_start()
-{
+do_start() {
+	oneshot start-pre
 	if is_call_implemented do_start_prepare; then
 		call do_start_prepare
 	fi
 	log_daemon_msg "Starting $DESC" "$NAME"
 	call do_start_cmd
 	retval=$?
+	if [ "$retval" = 0 ]; then
+		oneshot start-post
+	fi
 	if [ "$retval" = 1 ] && [ no != "$VERBOSE" ]; then
 		log_progress_msg "is already running"
 	fi
-	retval=$(( $retval > 1 ))
+	retval=$((retval > 1))
 	vlog_end_msg $retval
 	if is_call_implemented do_start_cleanup; then
 		call do_start_cleanup
@@ -103,18 +129,21 @@ do_stop_cmd() {
 	return $RETVAL
 }
 
-do_stop()
-{
+do_stop() {
+	oneshot stop-pre
 	if is_call_implemented do_stop_prepare; then
 		call do_stop_prepare
 	fi
 	vlog_daemon_msg "Stopping $DESC" "$NAME"
 	call do_stop_cmd
 	retval=$?
-	if [ "$retval" = 1 ] && [ no != "$VERBOSE" ] ; then
+	# Oneshot stop is unconditional
+	oneshot stop-post
+	if [ "$retval" = 1 ] && [ no != "$VERBOSE" ] &&
+		[ "$TYPE" != oneshot ]; then
 		log_progress_msg "is not running"
 	fi
-	retval=$(( $retval > 1 ))
+	retval=$((retval > 1))
 	vlog_end_msg $retval
 	if is_call_implemented do_stop_cleanup; then
 		call do_stop_cleanup
@@ -173,7 +202,11 @@ do_reload_sigusr1() {
 }
 
 do_status() {
+	if [ "$TYPE" = oneshot ]; then
+		oneshot status
+	else
 		status_of_proc ${PIDFILE:+-p "$PIDFILE"} "${DAEMON:-none}" "$NAME"
+	fi
 }
 
 if [ "$DEBUG" = "true" ]; then
@@ -183,7 +216,7 @@ fi
 # Unset configuration variables to make sure that if variable is not assigned a
 # value in init script, it does not use one from environment. See #822918.
 unset DAEMON DAEMON_ARGS DESC NAME COMMAND_NAME PIDFILE \
-    RELOAD_ARGS RELOAD_SIGNAL START_ARGS STOP_ARGS SETPRIV_ARGS
+	RELOAD_ARGS RELOAD_SIGNAL START_ARGS STOP_ARGS SETPRIV_ARGS TYPE
 
 SCRIPTNAME="$__init_d_script_name"
 scriptbasename=${__init_d_script_name##*/}
@@ -213,6 +246,9 @@ if [ none != "$DAEMON" ] && [ ! -x "$DAEMON" ] ; then
 	exit 0
 fi
 
+# Setup oneshot handling, if required
+oneshot setup
+
 # Do not use DAEMON or COMMAND_NAME if they are set to 'none'.
 [ none = "$DAEMON" ] && DAEMON=
 [ none = "$COMMAND_NAME" ] && COMMAND_NAME=
@@ -225,8 +261,7 @@ fi
 
 # Setup do_reload if not already defined
 if ! is_call_implemented do_reload; then
-	if ! is_call_implemented do_reload_cmd && [ -n "$RELOAD_SIGNAL" ]
-	then
+	if ! is_call_implemented do_reload_cmd && [ -n "$RELOAD_SIGNAL" ]; then
 		do_reload_cmd() { do_reload_signal; }
 	fi
 	if is_call_implemented do_reload_cmd; then
diff --git a/debian/init-d-script.5 b/debian/init-d-script.5
index a1e72cdf..45efd81b 100644
--- a/debian/init-d-script.5
+++ b/debian/init-d-script.5
@@ -71,6 +71,10 @@ the command name will not be used to match the processes.
 If unset, this variable defaults to the
 .Dq Ev NAME
 value.
+.It Ev TYPE
+If this variable is set to
+.Dq Li oneshot ,
+experimental support for a oneshot service is enabled.
 .It Ev PIDFILE
 Path to file where the process identifier of the started daemon
 will be stored during start.



More information about the Debian-init-diversity mailing list