[arch-projects] [initscripts] [PATCH 20/20] Catch all errors within status blocks
Kurt J. Bosch
kjb-temp-2009 at alpenjodel.de
Sun Jul 10 14:58:39 EDT 2011
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
More information about the arch-projects
mailing list