Change semantics of S and K files

Presently, there are a lot of special cases:
- runlevel 0 and 6 unconditionally run "script stop" if they
  find a Kxxscript symlink. This may lead to trying to stop an
  already stopped device if for example switching to runlevel 0/6
  from runlevel 1. This can be fixed by stating the convention
  that it is the responsability of scripts to check that the service
  is running before killing it (or not running before starting it).
  Still, we shouldn't try to stop a service if it was marked K in
  the previous runlevel. And same for S files: we shouldn't try to
  start a service that was marked S in the previous runlevel. Note
  that changing runlevel is not a "reset": if a user has manually
  changed the state of a daemon, this state will remain the same
  upon changing runlevel if the S/K status of that dameon is
  the same in both runlevels.

- Sxxscript symlinks in runlevel 0/6 are run as "script stop"
  instead of the more intuitive "script start". This does not interact
  well with LSB-tools (some scripts would need "Default-Start: S 0 6"
  but then it is impossible to get correct "Required-Start" or
  "Should-Start" fields). Furthermore, having a counter-intuitive
  behavior is error prone. So now runlevel 0/6 will run "script
  sart" for a Sxxscript.
This commit is contained in:
Pierre Labastie 2022-03-22 11:13:19 +01:00
parent 17c6532e0f
commit 27d23b1d41

View File

@ -6,10 +6,18 @@
#
# Authors : Gerard Beekmans - gerard@linuxfromscratch.org
# : DJ Lucas - dj@linuxfromscratch.org
# Update : Bruce Dubbs - bdubbs@linuxfromscratch.org
# Updates : Bruce Dubbs - bdubbs@linuxfromscratch.org
# : Pierre Labastie - pierre@linuxfromscratch.org
#
# Version : LFS 7.0
#
# Notes : Updates March 24th, 2022: new semantics of S/K files
# - Instead of testing that S scripts were K scripts in the
# previous runlevel, test that they were not S scripts
# - Instead of testing that K scripts were S scripts in the
# previous runlevel, test that they were not K scripts
# - S scripts in runlevel 0 or 6 are now run with
# "script start" (was "script stop" previously).
########################################################################
. /lib/lsb/init-functions
@ -144,8 +152,9 @@ fi
# Read the state file if it exists from runlevel S
[ -r /run/interactive ] && source /run/interactive
# Attempt to stop all services started by the previous runlevel,
# and killed in this runlevel
# Stop all services marked as K, except if marked as K in the previous
# runlevel: it is the responsibility of the script to not try to kill
# a non running service
if [ "${previous}" != "N" ]; then
for i in $(ls -v /etc/rc.d/rc${runlevel}.d/K* 2> /dev/null)
do
@ -155,20 +164,8 @@ if [ "${previous}" != "N" ]; then
continue
fi
suffix=${i#/etc/rc.d/rc$runlevel.d/K[0-9][0-9]}
prev_start=/etc/rc.d/rc$previous.d/S[0-9][0-9]$suffix
sysinit_start=/etc/rc.d/rcS.d/S[0-9][0-9]$suffix
if [ "${runlevel}" != "0" -a "${runlevel}" != "6" ]; then
if [ ! -f ${prev_start} -a ! -f ${sysinit_start} ]; then
MSG="WARNING:\n\n${i} can't be "
MSG="${MSG}executed because it was not "
MSG="${MSG}not started in the previous "
MSG="${MSG}runlevel (${previous})."
log_warning_msg "$MSG"
continue
fi
fi
suffix=${i#/etc/rc.d/rc${runlevel}.d/K[0-9][0-9]}
[ -e /etc/rc.d/rc${previous}.d/K[0-9][0-9]$suffix ] && continue
run ${i} stop
error_value=${?}
@ -184,31 +181,25 @@ if [ "$runlevel" == "6" -a -n "${FASTBOOT}" ]; then
fi
# Start all functions in this runlevel
# Start all services marked as S in this runlevel, except if marked as
# S in the previous runlevel
# it is the responsabily of the script to not try to start an already running
# service
for i in $( ls -v /etc/rc.d/rc${runlevel}.d/S* 2> /dev/null)
do
if [ "${previous}" != "N" ]; then
suffix=${i#/etc/rc.d/rc$runlevel.d/S[0-9][0-9]}
stop=/etc/rc.d/rc$runlevel.d/K[0-9][0-9]$suffix
prev_start=/etc/rc.d/rc$previous.d/S[0-9][0-9]$suffix
[ -f ${prev_start} -a ! -f ${stop} ] && continue
if [ "${previous}" != "N" ]; then
suffix=${i#/etc/rc.d/rc${runlevel}.d/S[0-9][0-9]}
[ -e /etc/rc.d/rc${previous}.d/S[0-9][0-9]$suffix ] && continue
fi
check_script_status
if [ "${SCRIPT_STAT}" == "1" ]; then
SCRIPT_STAT="0"
continue
fi
if [ "${SCRIPT_STAT}" == "1" ]; then
SCRIPT_STAT="0"
continue
fi
case ${runlevel} in
0|6)
run ${i} stop
;;
*)
run ${i} start
;;
esac
run ${i} start
error_value=${?}