Whitespace changes are introduced because of out status block indentation rule. I always attempted to make things more readable and elegant. First i changed five line if/stat_{done,fail} clauses into one liners using '&&' and '||'. Now i change these into two lines without any conditional constructs because whether stat_done or stat_fail is actually done no longer depends on the last command only, but on all commands within the status block. I thing the code would look better then ever before with this now. As said in the commit, it allows to catch errors caused by missing utmp group. It would also allow to catch errors caused by missing API-FS mountpoints or missing binaries called somewhere in the middle of a status block etc. I think we should avoid to say '[DONE]' in cases where actually only the last action succeeded in a multi actions block like 'Removing Leftover Files'. To get more fine grained error messages, we would just need to remove all std_err redirections where ever possible as done for cleaning /tmp/ here (by using correct patterns). In fact i think this makes the code more readable and avoiding hidden errors would make troubleshooting (a system where initscripts is installed) much easier. Actually all kinds of subshells and also function bodies aren't involved here as long as we don't use 'set -E'. trap 'echo err' ERR cat <( false ) # <<< you see nothing here unless you have done 'set -E' Yes, i also like TOFU (sometimes). -- Kurt Dave Reisner, 2011-07-10 21:30:
You've got large quantities of non-functional changes in here (whitespace churn), mixed in with reverts to your previous attempts at turning everything into a single line. Can we pick a direction and stick with it? This all seems like a lot of cleverness to accomplish... well... I'm not sure. What exactly _does_ this accomplish that we didn't previously have? If we want to be more fine grained about error checking as your rationale advertises, then let's do that so we can report a more detailed error than "[FAIL]".
I'm sure I've mentioned this before, but we value simplicity and readability in the initscripts. This is crucial code that cannot go foul because of some bash side effect we haven't considered. I'd rather be a little more verbose and make this easier to troubleshoot than to have to worry about write errors on process substitutions triggering magical ERR trap causing an echo somewhere to claim FAIL.
Yes, I know I'm top posting.
d
On Sun, Jul 10, 2011 at 08:58:39PM +0200, Kurt J. Bosch wrote:
Rationale: Instead of ignoring any errors of all commands but the last within a status block it is much better to use trap to catch them and report 'FAIL'. One might for example miss the utmp group which is needed to propperly install /var/run/utmp. This also makes the code a bit more simple and readable.
Note: We enable this explicitely (by calling stat_err_trap) because most daemon scriptlets don't work well with this by now. Moreover we don't use 'set -E' to avoid breaking/complicating [custom/hook] functions. --- functions | 10 ++++++++++ netfs | 12 ++++-------- rc.shutdown | 2 ++ rc.single | 2 ++ rc.sysinit | 59 +++++++++++++++++++++++++++++++++-------------------------- 5 files changed, 51 insertions(+), 34 deletions(-)
diff --git a/functions b/functions index d1d2947..ac5394c 100644 --- a/functions +++ b/functions @@ -125,11 +125,17 @@ stat_bkgd() { printf " ${C_OTHER}[${C_BKGD}BKGD${C_OTHER}]${C_CLEAR} " }
+# Allow to catch any errors and get the exit-code of the last failing command +stat_err_trap() { + trap 'STAT_ERR=$?' ERR +} + stat_busy() { printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} " printf "${SAVE_POSITION}" deltext printf " ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} " + STAT_ERR=0 }
stat_append() { @@ -139,6 +145,10 @@ stat_append() { }
stat_done() { + if (( STAT_ERR )); then + stat_fail + return $STAT_ERR + fi deltext printf " ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n" } diff --git a/netfs b/netfs index ea7e4eb..4dc91ef 100755 --- a/netfs +++ b/netfs @@ -4,24 +4,20 @@ . /etc/rc.conf . /etc/rc.d/functions
+stat_err_trap + case "$1" in start) stat_busy "Mounting Network Filesystems" mount -a -t "$NETFS" - rc=$? mount -a -O _netdev - (( rc || $? ))&& stat_die - add_daemon netfs - stat_done + stat_done&& add_daemon netfs || exit 1 ;; stop) stat_busy "Unmounting Network Filesystems" umount -a -O _netdev - rc=$? umount -a -t "$NETFS" - (( rc || $? ))&& stat_die - rm_daemon netfs - stat_done + stat_done&& rm_daemon netfs || exit 1 ;; restart) $0 stop diff --git a/rc.shutdown b/rc.shutdown index ed87eec..db4f12b 100755 --- a/rc.shutdown +++ b/rc.shutdown @@ -6,6 +6,8 @@ . /etc/rc.conf . /etc/rc.d/functions
+stat_err_trap + run_hook shutdown_start
# avoid staircase effect diff --git a/rc.single b/rc.single index 7a87c72..b5c6e66 100755 --- a/rc.single +++ b/rc.single @@ -6,6 +6,8 @@ . /etc/rc.conf . /etc/rc.d/functions
+stat_err_trap + run_hook single_start
if [[ $PREVLEVEL != N ]]; then diff --git a/rc.sysinit b/rc.sysinit index 97c16c8..be8eb05 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -6,6 +6,8 @@ . /etc/rc.conf . /etc/rc.d/functions
+stat_err_trap + echo " " printhl "Arch Linux\n" printhl "${C_H2}http://www.archlinux.org" @@ -14,17 +16,19 @@ printsep run_hook sysinit_start
# mount /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm (the api filesystems) -mountpoint -q /proc || mount -n -t proc proc /proc -o nosuid,noexec,nodev -mountpoint -q /sys || mount -n -t sysfs sys /sys -o nosuid,noexec,nodev -mountpoint -q /run || mount -n -t tmpfs run /run -o mode=0755,size=10M,nosuid,nodev -mountpoint -q /dev || mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid&>/dev/null \ - || mount -n -t tmpfs udev /dev -o mode=0755,size=10M,nosuid -mkdir -p -m 1777 /run/lock -mkdir -p /dev/{pts,shm} -mountpoint -q /dev/pts || mount -n /dev/pts&>/dev/null \ - || mount -n -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec -mountpoint -q /dev/shm || mount -n /dev/shm&>/dev/null \ - || mount -n -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev +stat_busy "Mounting API Filesystems" + mountpoint -q /proc || mount -n -t proc proc /proc -o nosuid,noexec,nodev + mountpoint -q /sys || mount -n -t sysfs sys /sys -o nosuid,noexec,nodev + mountpoint -q /run || mount -n -t tmpfs run /run -o mode=0755,size=10M,nosuid,nodev + mountpoint -q /dev || mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid&>/dev/null \ + || mount -n -t tmpfs udev /dev -o mode=0755,size=10M,nosuid + mkdir -p -m 1777 /run/lock + mkdir -p /dev/{pts,shm} + mountpoint -q /dev/pts || mount -n /dev/pts&>/dev/null \ + || mount -n -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec + mountpoint -q /dev/shm || mount -n /dev/shm&>/dev/null \ + || mount -n -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev +stat_done
# remount root ro to allow for fsck later on, we remount now to # make sure nothing can open files rw on root which would block a remount @@ -46,7 +50,7 @@ esac if [[ $HWCLOCK_PARAMS ]]; then stat_busy "Adjusting system time and setting kernel timezone" # enable rtc access - modprobe -q -a rtc-cmos rtc genrtc + modprobe -q -a rtc-cmos rtc genrtc || : # If devtmpfs is used, the required RTC device already exists now # Otherwise, create whatever device is available if ! [[ -c /dev/rtc || -c /dev/rtc0 ]]; then @@ -65,7 +69,8 @@ if [[ $HWCLOCK_PARAMS ]]; then # is used. If HARDWARECLOCK is not set in rc.conf, the value in # /var/lib/hwclock/adjfile is used (in this case /var can not be a separate # partition). - TZ=$TIMEZONE hwclock $HWCLOCK_PARAMS&& stat_done || stat_fail + TZ=$TIMEZONE hwclock $HWCLOCK_PARAMS + stat_done fi
# Start/trigger UDev, load MODULES and settle UDev @@ -89,7 +94,7 @@ activate_vgs # Set up non-root encrypted partition mappings if [[ -f /etc/crypttab&& $CS ]]&& grep -q ^[^#] /etc/crypttab; then stat_busy "Unlocking encrypted volumes:" - modprobe -q dm-crypt 2>/dev/null + modprobe -q dm-crypt 2>/dev/null || : do_unlock() { # $1 = requested name # $2 = source device @@ -167,8 +172,9 @@ if [[ -f /etc/crypttab&& $CS ]]&& grep -q ^[^#] /etc/crypttab; then fi return $failed } - crypto_unlocked=0 - read_crypttab do_unlock&& stat_done || stat_fail + crypto_unlocked=0 + read_crypttab do_unlock + stat_done # Maybe someone has LVM on an encrypted block device (( crypto_unlocked == 1 ))&& activate_vgs fi @@ -177,14 +183,13 @@ fi [[ -f /forcefsck || " $(< /proc/cmdline) " =~ [[:blank:]]forcefsck[[:blank:]] ]]&& FORCEFSCK="-- -f" declare -r FORCEFSCK run_hook sysinit_prefsck +fsckret=0 if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems" - fsck_all>|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} - declare -r fsckret=$? + fsck_all>|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} || fsckret=$? (( fsckret<= 1 ))&& stat_done || stat_fail -else - declare -r fsckret=0 fi +declare -r fsckret run_hook sysinit_postfsck
# Single-user login and/or automatic reboot if needed @@ -201,7 +206,7 @@ if [[ ! -L /etc/mtab ]]; then else cat /proc/mounts>| /etc/mtab fi - (( $? == 0 ))&& stat_done || stat_fail + stat_done fi
# now mount all the local filesystems @@ -227,7 +232,7 @@ RANDOM_SEED=/var/lib/misc/random-seed cp $RANDOM_SEED /dev/urandom
stat_busy "Removing Leftover Files" - rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.* /var/run/daemons&>/dev/null + rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons [[ -d /var/lock&& $(stat -f -c %T -L /var/lock) != tmpfs ]]&& rm -rf /var/lock/* if [[ -d /var/run&& $(stat -f -c %T -L /var/run) != tmpfs ]]; then find /var/run/ \! -type d -delete @@ -240,13 +245,15 @@ stat_done
if [[ $HOSTNAME ]]; then stat_busy "Setting Hostname: $HOSTNAME" - echo "$HOSTNAME">| /proc/sys/kernel/hostname&& stat_done || stat_fail + echo "$HOSTNAME">| /proc/sys/kernel/hostname + stat_done fi
# Flush old locale settings and set user defined locale stat_busy "Setting Locale: ${LOCALE:=en_US}" - echo "export LANG=$LOCALE"> /etc/profile.d/locale.sh&& -chmod 0755 /etc/profile.d/locale.sh&& stat_done || stat_fail + echo "export LANG=$LOCALE"> /etc/profile.d/locale.sh + chmod 0755 /etc/profile.d/locale.sh +stat_done
if [[ ${LOCALE,,} =~ utf ]]; then stat_busy "Setting Consoles to UTF-8 mode" @@ -282,7 +289,7 @@ stat_busy "Saving dmesg Log" else install -Tm 0644<( dmesg ) /var/log/dmesg.log fi -(( $? == 0 ))&& stat_done || stat_fail +stat_done
run_hook sysinit_end
-- 1.7.1