[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