--JvQQkW7dTDapIRoU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
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
--JvQQkW7dTDapIRoU
Content-Type: text/x-dsrc; charset=us-ascii
Content-Disposition: attachment; filename="acct.init.d"
#!/bin/sh
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides: acct
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: process and login accounting
# Description: GNU Accounting Utilities is a set of utilities which
# reports and summarizes data about user connect times and
# process execution statistics.
### END INIT INFO
DAEMON=/usr/sbin/accton
NAME�ct
DESC="process accounting"
caps="-all,+sys_pacct"
SETPRIV_ARGS="--inh-caps $caps --ambient-caps $caps --bounding-set $caps --no-new-privs"
# Thanks: oneshot pattern for init-d-script devised by Mark Hindley and
# and adapted for acct by Andrew Bower.
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
}
do_start_prepare() {
[ -f /run/$NAME.oneshot ] && exit
}
do_stop_prepare() {
[ -f /run/$NAME.oneshot ] || exit
}
do_stop_cleanup() {
rm -f /run/$NAME.oneshot
}
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
}
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"
run_accton "$file"
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
return 0
fi
return 2
}
do_stop_cmd_override() {
run_accton off
}
--JvQQkW7dTDapIRoU--
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEMKYZL6LI55lncG11uqgO2W94h+kFAmhtZzYACgkQuqgO2W94 h+m24hAAj49Pq4pJokOgMc+t5NIZLs2ITfPK5K7rqe2DKTMwTi1p5lr8VqmlgbX4 D+hQ8puvndWN58vBoUtbmP3f5fzvY04I5i7QiI2UkRdjnRSfYUhwvIrQaLxlo2vN DkEN3dg1bKWhv6ywOKQ8aHuwyj60FTQAu29MAd05tctdrzlVUuOopxXINR1rsxGN mob1uSMhz5zJuZCt2HdIjXBkyPsrywrQFoLqtIJ9S9jmEQFRRMdMJ5GNptD9eWAx 5hkR2XC6UZUyhIYKLgSeFKxs2nJYiv1YI06KcXKfSGJ8MlFX9WqeQIEfdcvo40ll dBvaSNNkYffLJl690hsrm737HQyEQvbawMkl5NvQS6y1XxYKrarvbwJ0dOSEXZYG A0LjY/e+CBcTfG0DgTEhO4Cm4AMqY1YiD0gYMetU72BTHC7D3NwhotZKoPV+kVR8 HXGUPuduziKnCORmHYb2A+40m0g1rS1Kt9RhRZli5EW0sgVW5AAmgCTiAX4j0Dny NioUuste6Ft2bzm+gq/sOWqN9emx+ovOy47TSSHirCeqdMjehdgSveNxnOb0CvGn OGeS+rasqrhAUgtV4XWaz5b8YrqP9P/JdMCMo399WwKFqf8CNtmFzpz8D5MU4tAz oHT9hPTQpUo3kRdDcGAMrhuQM91DZWKyUaaraiVR//FC2xiZu4Y=
=j45T
-----END PGP SIGNATURE-----
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)