Bug#1108969: sysvinit-utils: add common support for oneshot services in init-d-script helper
Andrew Bower
andrew at bower.uk
Tue Jul 8 19:45:13 BST 2025
Package: sysvinit-utils
Version: 3.14-4
Severity: wishlist
Dear Maintainer,
Mark outlined an approach for implementing single-shot services in
https://www.chiark.greenend.org.uk/pipermail/debian-init-diversity/2025-March/007475.html
and suggested that this could be incorporated as common functionality
in the init-d-script(5) helper script.
I support this idea. In the case of services that occur strictly at boot
time and shutdown, I think the traditional pattern of detecting the
runlevel transition [1] is sufficient but for services in the multi-user
runlevels, the flag file seems more appropriate.
I have applied this pattern to my reworking of the initscript for the
'acct' package [2] and as a result have some feedback potentially to
improve the solution.
I attach the proposed final state of the script and quote snippets here
as context for suggestions about the common solution.
> DAEMON=/usr/sbin/accton
init-d-script(5) says not to set DAEMON unless you are actually starting
a daemon but I don't see a problem with using it for a command related
to the one-shot operation as it then doubles as the 'installed' check,
allows repeated use of the variable within the script while benefiting
from the logic that prevents it being overriden by the 'defaults' file
and avoids finding another variable name to use for a near-identical
purpose. So I used it.
> run_accton() {
> # Borrowed from init-d-script:
> if [ "$SETPRIV_ARGS" ] ; then
> PATH=/bin:/usr/bin command -v setpriv > /dev/null 2>&1 || unset SETPRIV_ARGS
> fi
>
> ${SETPRIV_ARGS:+setpriv $SETPRIV_ARGS} $DAEMON "$@" >/dev/null 2>/dev/null
> }
It would be helpful if this logic could be available for 'oneshot'
services rather than being defined in the built-in do_start_cmd().
> do_start_prepare() {
> [ -f /run/$NAME.oneshot ] && exit
> }
>
> do_stop_prepare() {
> [ -f /run/$NAME.oneshot ] || exit
> }
>
> do_stop_cleanup() {
> rm -f /run/$NAME.oneshot
I removed the '-v' - I don't think we want that console noise.
> }
>
> do_status_override() {
> if [ -f /run/$NAME.oneshot ]; then
> log_success_msg "$NAME is running"
> else
> log_failure_msg "$NAME is not running"
> return 4
> fi
> }
We could do with a default status operation. This supports compound
operations like 'try-restart' that are needed in logrotate post-rotation
scripts, etc.
> do_start_cmd_override() {
>
> # Allow the log file preparation commands to fail - defer errors to accton
> file="/var/log/account/pacct"
> mkdir -p "$(dirname $file)"
> touch "$file"
> chmod 640 "$file"
> chown root:adm "$file"
This is acct-specific, of course. Hopefully we'll be able to use the
'do_start_prepare()' override once that isn't needed for the oneshot
preparation.
>
> run_accton "$file"
The run operation was factored out to a common function to avoid code
duplication invoking 'setpriv' but would be clearer and more succinct if
the key command was simply invoked here in full, perhaps preceded with a
setpriv-related variable that has been set up by the helper code for us.
> rv=$?
> if [ $rv -eq 38 ]; then #ENOSYS
> log_warning_msg "Process accounting not available with this kernel."
> elif [ $rv -eq 16 ]; then #EBUSY
> log_warning_msg "Process accounting already enabled on this system."
> elif [ $rv -eq 1 ]; then #EPERM
> log_warning_msg "Insufficient privileges."
> elif [ $rv -eq 0 ]; then
> touch /run/$NAME.oneshot
I moved this here instead of in do_start_cleanup() because touching the
flag file needs to be conditional on a successful return code, but the
cleanup function doesn't have access to the return code, except by
cheating and inspecting the $retval global which is an implementation
detail of the library functions. It would be nice to shape the helper
code so that this can be done automatically on a successful return code
from do_start_cmd_override().
> return 0
> fi
> return 2
We could do with translating the return code. If 1 is returned on error,
for example, the service is reported as already running instead of as
having failed to be started, hence returning 2.
> }
>
> do_stop_cmd_override() {
> run_accton off
> }
I hope these thoughts help with any future implementation of common
single shot init script support.
Many thanks again for the initial proposal, Mark!
Andrew
[1] https://sources.debian.org/src/wtmpdb/0.73.0-3/debian/wtmpdb.wtmpdb-update-boot.init/
[2] https://salsa.debian.org/pkg-security-team/acct/-/merge_requests/8
-------------- next part --------------
A non-text attachment was scrubbed...
Name: acct.init.d
Type: text/x-dsrc
Size: 2127 bytes
Desc: not available
URL: <http://www.chiark.greenend.org.uk/pipermail/debian-init-diversity/attachments/20250708/ac185c99/attachment.d>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://www.chiark.greenend.org.uk/pipermail/debian-init-diversity/attachments/20250708/ac185c99/attachment.sig>
More information about the Debian-init-diversity
mailing list