OK. Now i changed some of these as suggested by Tom and also dropped the status() redirection thing and the is_array() replacement. (Good point about the redirection error not catched!) Furthermore i added rc.sysinit: Remove unneeded variables initializations (as suggested) and at the end some new ones.
Kurt J. Bosch (20): functions/rc.single: Clean up whitespace rc.sysinit: Fix stat_busy block indentation functions: Get rid of superfluous braces in udevd_modprobe() functions: Add missing quotes in mount_all() functions/rc.multi: Strip paths from binaries Refactor kill_everything, fsck_all and mount_all code rc.sysinit: Declare $FORCEFSCK read-only functions/rc.sysinit: Refactor fsck-redirection to prevent breakage rc.sysinit: Remove unneeded variables initializations functions: Make status() return the actual exit code Deprecate in_array() functions: Speed up reboot/shutdown by recognizing killall5 exit code 2 netfs: cleanup whitespace netfs: Strip paths from binaries netfs: Refactor to provide meaningful exit code functions/netfs: Refactor filesystem type lists and $NETFS rc.sysinit: Simplify /var/run/daemons workaround rc.sysinit: Make Removing Leftover Files more smart rc.single: Remove $PATH assignment Catch all errors within status blocks
functions | 126 ++++++++++++++++++++++++++++++++--------------------------- netfs | 29 ++++--------- rc.multi | 2 +- rc.shutdown | 10 ++++- rc.single | 15 +++++-- rc.sysinit | 77 +++++++++++++++++++++++------------- 6 files changed, 147 insertions(+), 112 deletions(-)
--- functions | 2 +- rc.single | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/functions b/functions index bcc97c1..f82110d 100644 --- a/functions +++ b/functions @@ -320,7 +320,7 @@ udevd_modprobe() { udevadm settle --timeout=${UDEV_TIMEOUT:-30}
run_hook "${1}_udevsettled" - + # in case loading a module changed the display mode calc_columns } diff --git a/rc.single b/rc.single index d630736..d1efd41 100755 --- a/rc.single +++ b/rc.single @@ -12,10 +12,10 @@ run_hook single_start
if [[ $PREVLEVEL != N ]]; then kill_everything single - + # start up our mini logger until syslog takes over minilogd - + # Start/trigger UDev, load MODULES and settle UDev udevd_modprobe single fi
The general rule is now: Align stat_{fail,done} with stat_busy --- rc.sysinit | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index 7b086fa..cb0144c 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -231,7 +231,7 @@ 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 +chmod 0755 /etc/profile.d/locale.sh && stat_done || stat_fail
if [[ ${LOCALE,,} =~ utf ]]; then stat_busy "Setting Consoles to UTF-8 mode"
Braces are not needed in this case as a variable name can not begin with a number. --- functions | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/functions b/functions index f82110d..71b49e3 100644 --- a/functions +++ b/functions @@ -305,7 +305,7 @@ udevd_modprobe() { # This is used to determine which hooks to run. status "Starting UDev Daemon" udevd --daemon
- run_hook "${1}_udevlaunched" + run_hook "$1_udevlaunched"
stat_busy "Triggering UDev uevents" udevadm trigger --action=add --type=subsystems @@ -319,7 +319,7 @@ udevd_modprobe() { status "Waiting for UDev uevents to be processed" \ udevadm settle --timeout=${UDEV_TIMEOUT:-30}
- run_hook "${1}_udevsettled" + run_hook "$1_udevsettled"
# in case loading a module changed the display mode calc_columns
Prevent any word splitting where not intended. --- functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index 71b49e3..ec043b6 100644 --- a/functions +++ b/functions @@ -417,7 +417,7 @@ fsck_reboot() { mount_all() { stat_busy "Mounting Local Filesystems" run_hook sysinit_premount - mount -a -t $NETFS -O no_netdev + mount -a -t "$NETFS" -O no_netdev run_hook sysinit_postmount stat_done }
Now that we set PATH in functions, we can use is everywhere. --- functions | 42 +++++++++++++++++++++--------------------- rc.multi | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/functions b/functions index ec043b6..7acb855 100644 --- a/functions +++ b/functions @@ -20,12 +20,12 @@ calc_columns () { USECOLOR="" elif [[ -t 0 ]]; then # stty will fail when stdin isn't a terminal - STAT_COL="$(/bin/stty size)" + STAT_COL="$(stty size)" # stty gives "rows cols"; strip the rows number, we just want columns STAT_COL="${STAT_COL##* }" - elif /bin/tput cols &>/dev/null; then + elif tput cols &>/dev/null; then # is /usr/share/terminfo already mounted, and TERM recognized? - STAT_COL=$(/bin/tput cols) + STAT_COL=$(tput cols) fi if (( STAT_COL == 0 )); then # if output was 0 (serial console), set default width to 80 @@ -50,7 +50,7 @@ calc_columns () { calc_columns
# disable colors on broken terminals -TERM_COLORS="$(/bin/tput colors 2>/dev/null)" +TERM_COLORS="$(tput colors 2>/dev/null)" if (( $? != 3 )); then case $TERM_COLORS in *[!0-9]*) USECOLOR="";; @@ -75,17 +75,17 @@ fi
# set colors if [[ $USECOLOR = [yY][eE][sS] ]]; then - if /bin/tput setaf 0 &>/dev/null; then + if tput setaf 0 &>/dev/null; then C_CLEAR="$(tput sgr0)" # clear text - C_MAIN="${C_CLEAR}$(/bin/tput bold)" # main text - C_OTHER="${C_MAIN}$(/bin/tput setaf 4)" # prefix & brackets - C_SEPARATOR="${C_MAIN}$(/bin/tput setaf 0)" # separator - C_BUSY="${C_CLEAR}$(/bin/tput setaf 6)" # busy - C_FAIL="${C_MAIN}$(/bin/tput setaf 1)" # failed + C_MAIN="${C_CLEAR}$(tput bold)" # main text + C_OTHER="${C_MAIN}$(tput setaf 4)" # prefix & brackets + C_SEPARATOR="${C_MAIN}$(tput setaf 0)" # separator + C_BUSY="${C_CLEAR}$(tput setaf 6)" # busy + C_FAIL="${C_MAIN}$(tput setaf 1)" # failed C_DONE="${C_MAIN}" # completed - C_BKGD="${C_MAIN}$(/bin/tput setaf 5)" # backgrounded + C_BKGD="${C_MAIN}$(tput setaf 5)" # backgrounded C_H1="${C_MAIN}" # highlight text 1 - C_H2="${C_MAIN}$(/bin/tput setaf 6)" # highlight text 2 + C_H2="${C_MAIN}$(tput setaf 6)" # highlight text 2 else C_CLEAR="\e[m" # clear text C_MAIN="\e[;1m" # main text @@ -179,12 +179,12 @@ in_array() { # daemons:
add_daemon() { - [[ -d /run/daemons ]] || /bin/mkdir -p /run/daemons + [[ -d /run/daemons ]] || mkdir -p /run/daemons >| /run/daemons/"$1" }
rm_daemon() { - /bin/rm -f /run/daemons/"$1" + rm -f /run/daemons/"$1" }
ck_daemon() { @@ -287,13 +287,13 @@ kill_everything() { # Terminate all processes stat_busy "Sending SIGTERM To Processes" run_hook "$1_prekillall" - /sbin/killall5 -15 ${omit_pids[@]/#/-o } &>/dev/null - /bin/sleep 5 + killall5 -15 ${omit_pids[@]/#/-o } &>/dev/null + sleep 5 stat_done
stat_busy "Sending SIGKILL To Processes" - /sbin/killall5 -9 ${omit_pids[@]/#/-o } &>/dev/null - /bin/sleep 1 + killall5 -9 ${omit_pids[@]/#/-o } &>/dev/null + sleep 1 stat_done
run_hook "$1_postkillall" @@ -329,8 +329,8 @@ activate_vgs() { [[ $USELVM = [yY][eE][sS] && -x $(type -P lvm) && -d /sys/block ]] || return 0 # Kernel 2.6.x, LVM2 groups stat_busy "Activating LVM2 groups" - /sbin/modprobe -q dm-mod 2>/dev/null - /sbin/vgchange --sysinit -a y >/dev/null + modprobe -q dm-mod 2>/dev/null + vgchange --sysinit -a y >/dev/null (( $? == 0 )) && stat_done || stat_fail }
@@ -496,7 +496,7 @@ set_consolefont() { [[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do - /usr/bin/setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ + setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ $CONSOLEFONT -C ${i} &>/dev/null done if (( $? )); then diff --git a/rc.multi b/rc.multi index b801fb6..16fa83a 100755 --- a/rc.multi +++ b/rc.multi @@ -9,7 +9,7 @@ run_hook multi_start
# Load sysctl variables if sysctl.conf is present -[[ -r /etc/sysctl.conf ]] && /sbin/sysctl -q -p &>/dev/null +[[ -r /etc/sysctl.conf ]] && sysctl -q -p &>/dev/null
# Start daemons for daemon in "${DAEMONS[@]}"; do
Genaral scheme for hook positions is now:
run_hook pre_foo if [[$WE_WANT_TO_DO_FOO]]]; then stat_busy "Doing foo" if [[$PRECONDITIONS_FOR_FOO_NOT_SATISFIED]]; then stat_fail else ... stat_done fi fi run hook post_foo
rc.sysinit ----------- run_hook pre_foo [[$WE_WANT_TO_DO_FOO]] && status "Doing foo" foo run hook post_foo
functions ------------ foo() { [[$PRECONDITIONS_FOR_FOO_NOT_SATISFIED]] && return 1 ... }
Rationale
Following this scheme as close as possible (without duplicating code and status messages) makes stuff more readable and uniform. Splitting kill_everything() into two new functions stop_all_daemons() and kill_all() also allows customization of either daemons stopping or process killing in an easy way.
Suggested-by: Tom Gundersen teg@jklm.no --- functions | 36 +++++++++++------------------------- rc.shutdown | 8 +++++++- rc.single | 9 ++++++++- rc.sysinit | 24 +++++++++++++++++++++--- 4 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/functions b/functions index 7acb855..fd18694 100644 --- a/functions +++ b/functions @@ -265,10 +265,10 @@ add_omit_pids() { omit_pids+=( $@ ) }
- -kill_everything() { - # $1 = where we are being called from. - # This is used to determine which hooks to run. +# Stop all daemons +# This function should *never* ever perform any other actions beside calling stop_daemon()! +# It might be used by a splash system etc. to get a list of daemons to be stopped. +stop_all_daemons() { # Find daemons NOT in the DAEMONS array. Shut these down first local daemon for daemon in /run/daemons/*; do @@ -283,10 +283,11 @@ kill_everything() { [[ ${DAEMONS[i]} = '!'* ]] && continue ck_daemon ${DAEMONS[i]#@} || stop_daemon ${DAEMONS[i]#@} done +}
+kill_all() { # Terminate all processes stat_busy "Sending SIGTERM To Processes" - run_hook "$1_prekillall" killall5 -15 ${omit_pids[@]/#/-o } &>/dev/null sleep 5 stat_done @@ -295,8 +296,6 @@ kill_everything() { killall5 -9 ${omit_pids[@]/#/-o } &>/dev/null sleep 1 stat_done - - run_hook "$1_postkillall" }
# Start/trigger UDev, load MODULES and settle UDev @@ -360,23 +359,14 @@ read_crypttab() { return $failed }
+# Filesystem functions +# These can be overridden/reused for customizations like shutdown/loop-fsck. NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs,nodavfs"
# Check local filesystems fsck_all() { - [[ -x $(type -P fsck) ]] || return 0 - stat_busy "Checking Filesystems" - FSCK_OUT=/dev/stdout - FSCK_ERR=/dev/stdout - FSCK_FD= - FORCEFSCK= - [[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" - run_hook sysinit_prefsck - fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK >|$FSCK_OUT 2>|$FSCK_ERR - local -r fsckret=$? - (( fsckret <= 1 )) && stat_done || stat_fail - run_hook sysinit_postfsck - return $fsckret + fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK >|$FSCK_OUT 2>|$FSCK_ERR + return $? }
# Single-user login and/or automatic reboot after fsck (if needed) @@ -415,11 +405,7 @@ fsck_reboot() { }
mount_all() { - stat_busy "Mounting Local Filesystems" - run_hook sysinit_premount - mount -a -t "$NETFS" -O no_netdev - run_hook sysinit_postmount - stat_done + mount -a -t "$NETFS" -O no_netdev }
bootlogd_stop() { diff --git a/rc.shutdown b/rc.shutdown index fe42797..ed87eec 100755 --- a/rc.shutdown +++ b/rc.shutdown @@ -17,7 +17,13 @@ echo " "
[[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown
-kill_everything shutdown +stop_all_daemons + +run_hook shutdown_prekillall + +kill_all + +run_hook shutdown_postkillall
stat_busy "Saving Random Seed" RANDOM_SEED=/var/lib/misc/random-seed diff --git a/rc.single b/rc.single index d1efd41..21fe3be 100755 --- a/rc.single +++ b/rc.single @@ -11,7 +11,14 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" run_hook single_start
if [[ $PREVLEVEL != N ]]; then - kill_everything single + + stop_all_daemons + + run_hook single_prekillall + + kill_all + + run_hook single_postkillall
# start up our mini logger until syslog takes over minilogd diff --git a/rc.sysinit b/rc.sysinit index cb0144c..c3610dc 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -174,9 +174,24 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi
# Check filesystems -fsck_all +FSCK_OUT=/dev/stdout +FSCK_ERR=/dev/stdout +FSCK_FD= +FORCEFSCK= +[[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" +run_hook sysinit_prefsck +if [[ -x $(type -P fsck) ]]; then + stat_busy "Checking Filesystems" + fsck_all + declare -r fsckret=$? + (( fsckret <= 1 )) && stat_done || stat_fail +else + declare -r fsckret=0 +fi +run_hook sysinit_postfsck + # Single-user login and/or automatic reboot if needed -fsck_reboot $? +fsck_reboot $fsckret
status "Remounting Root Read/Write" \ mount -n -o remount,rw / @@ -193,7 +208,10 @@ if [[ ! -L /etc/mtab ]]; then fi
# now mount all the local filesystems -mount_all +run_hook sysinit_premount +status "Mounting Local Filesystems" \ + mount_all +run_hook sysinit_postmount
# enable monitoring of lvm2 groups, now that the filesystems are mounted rw [[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
This prevents sysinit_prefsck hooks from overwriting the value. --- rc.sysinit | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index c3610dc..f64c9ad 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -179,6 +179,7 @@ FSCK_ERR=/dev/stdout FSCK_FD= FORCEFSCK= [[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" +declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems"
$FSCK_OUT/$FSCK_ERR might not be set when: * unset in some custom sysinit_prefsck hook * calling fsck() from a shutdown hook --- functions | 2 +- rc.sysinit | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/functions b/functions index fd18694..202db30 100644 --- a/functions +++ b/functions @@ -365,7 +365,7 @@ NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuse
# Check local filesystems fsck_all() { - fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK >|$FSCK_OUT 2>|$FSCK_ERR + fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK return $? }
diff --git a/rc.sysinit b/rc.sysinit index f64c9ad..5814007 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -174,8 +174,8 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi
# Check filesystems -FSCK_OUT=/dev/stdout -FSCK_ERR=/dev/stdout +FSCK_OUT= +FSCK_ERR= FSCK_FD= FORCEFSCK= [[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" @@ -183,7 +183,7 @@ declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems" - fsck_all + fsck_all >|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} declare -r fsckret=$? (( fsckret <= 1 )) && stat_done || stat_fail else
Variables should be empty anyway here. --- rc.sysinit | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index 5814007..4132b8c 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -174,10 +174,6 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi
# Check filesystems -FSCK_OUT= -FSCK_ERR= -FSCK_FD= -FORCEFSCK= [[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" declare -r FORCEFSCK run_hook sysinit_prefsck
The exit code returned by the given command might be useful/expected, so don't discard but return it. --- functions | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/functions b/functions index 202db30..6efcd52 100644 --- a/functions +++ b/functions @@ -156,12 +156,10 @@ stat_die() { status() { stat_busy "$1" shift - if "$@" &>/dev/null; then - stat_done - return 0 - fi - stat_fail - return 1 + "$@" &>/dev/null + local ret=$? + (( $ret == 0 )) && stat_done || stat_fail + return $ret }
# usage : in_array( $needle, $haystack )
in_array() strips '@' and therefore the name is missleading. For checking DAEMONS, ck_autostart() should be used. --- functions | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/functions b/functions index 6efcd52..caa9060 100644 --- a/functions +++ b/functions @@ -162,10 +162,15 @@ status() { return $ret }
-# usage : in_array( $needle, $haystack ) +# This is deprecated! +# It strips '@' and therefore the name is missleading. +# For checking DAEMONS, ck_autostart() should be used! +# +# usage : is_in_array( $needle, $haystack ) # return : 0 - found # 1 - not found in_array() { + echo "WARNING: Call to deprecated function in_array() from $0" >&2 local needle=$1; shift local item for item; do @@ -272,7 +277,7 @@ stop_all_daemons() { for daemon in /run/daemons/*; do [[ -f $daemon ]] || continue daemon=${daemon##*/} - in_array "$daemon" "${DAEMONS[@]}" || stop_daemon "$daemon" + ck_autostart "$daemon" && stop_daemon "$daemon" done
# Shutdown daemons in reverse order
in_array() strips '@' and therefore the name is missleading. For checking DAEMONS, ck_autostart() should be used. --- functions | 7 ++++++- rc.sysinit | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/functions b/functions index 6efcd52..d594c3e 100644 --- a/functions +++ b/functions @@ -162,10 +162,15 @@ status() { return $ret }
+# This is deprecated! +# It strips '@' and therefore the name is missleading. +# For checking DAEMONS, ck_autostart() should be used! +# # usage : in_array( $needle, $haystack ) # return : 0 - found # 1 - not found in_array() { + echo "WARNING: Call to deprecated function in_array() from $0" >&2 local needle=$1; shift local item for item; do @@ -272,7 +277,7 @@ stop_all_daemons() { for daemon in /run/daemons/*; do [[ -f $daemon ]] || continue daemon=${daemon##*/} - in_array "$daemon" "${DAEMONS[@]}" || stop_daemon "$daemon" + ck_autostart "$daemon" && stop_daemon "$daemon" done
# Shutdown daemons in reverse order diff --git a/rc.sysinit b/rc.sysinit index 4132b8c..2ef85e6 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -174,7 +174,7 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi
# Check filesystems -[[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" +[[ -f /forcefsck || " $(< /proc/cmdline) " =~ [[:blank:]]forcefsck[[:blank:]] ]] && FORCEFSCK="-- -f" declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then
On Sun, Jul 10, 2011 at 7:26 PM, Kurt J. Bosch kjb-temp-2009@alpenjodel.de wrote:
in_array() strips '@' and therefore the name is missleading. For checking DAEMONS, ck_autostart() should be used.
Here you introduce a change not mentioned in the commit message: in_array is used to check for forcefsck, so this patch does this inline instead (which makes me more hesitant than before to apply it).
Changing in_array to ck_autostart would be fine, but I don't see the benefit of deprecating in_array. If in_array() has a bug, then we should fix it, if this causes regressions then they should be fixed, if they cannot be fixed we might consider adding a new is_in_array and deprecating the old one. However, I'd rather not derpecate/change/add functions unless we must.
If there are bugs out there that I'm not aware of, and that would be fixed by this patch, please let me know.
Cheers,
Tom
OK, as fbsplash-extras (AUR) doesn't use in_array for DAEMONS anymore and i don't know about any others, these might be better (more straigth forward).
Kurt J. Bosch (3): functions: Use ck_autostart in stop_all_daemons() rc.sysinit: fixup fsck refactoring functions: Make in_array() non DAEMONS specific
functions | 4 ++-- rc.sysinit | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
This is just a bit simpler. in_array() should be fixed to be non daemon specific in a later patch. --- functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index 5bfeb77..f564f3d 100644 --- a/functions +++ b/functions @@ -272,7 +272,7 @@ stop_all_daemons() { for daemon in /run/daemons/*; do [[ -f $daemon ]] || continue daemon=${daemon##*/} - in_array "$daemon" "${DAEMONS[@]}" || stop_daemon "$daemon" + ck_autostart "$daemon" && stop_daemon "$daemon" done
# Shutdown daemons in reverse order
Revert to using in_array() instead of is_in_array() which actually doesn't exist. --- rc.sysinit | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index 7357582..bfaaf1b 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -174,7 +174,7 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi
# Check filesystems -[[ -f /forcefsck ]] || is_in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" +[[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline) && FORCEFSCK="-- -f" declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then
For checking whether a daemon is started via the DAEMONS array we use ck_autostart() now. So make in_array() generic as the name suggests instead of removing '@'-prefixes from array members behind ones back.
Suggested-by: Dave Reisner d@falconindy.com --- functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index f564f3d..000ee0e 100644 --- a/functions +++ b/functions @@ -169,7 +169,7 @@ in_array() { local needle=$1; shift local item for item; do - [[ ${item#@} = $needle ]] && return 0 + [[ $item = $needle ]] && return 0 done return 1 # Not Found }
killall5 returns 2 if it didn't find any processes to send to. Using this avoids sleeping longer than needed. This saves another up to six seconds of reboot/shutdown/go-single time. --- functions | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/functions b/functions index caa9060..09655ab 100644 --- a/functions +++ b/functions @@ -290,14 +290,25 @@ stop_all_daemons() {
kill_all() { # Terminate all processes + # and wait until killall5 reports all done or timeout + # Unfortunately killall5 does not support the 0 signal, so just + # use SIGCONT for checking (which should be ignored). stat_busy "Sending SIGTERM To Processes" + local i killall5 -15 ${omit_pids[@]/#/-o } &>/dev/null - sleep 5 + for (( i=0; i<20 && $?!=2; i++ )); do + sleep .25 # 1/4 second + killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null + done stat_done
stat_busy "Sending SIGKILL To Processes" + local i killall5 -9 ${omit_pids[@]/#/-o } &>/dev/null - sleep 1 + for (( i=0; i<4 && $?!=2; i++ )); do + sleep .25 # 1/4 second + killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null + done stat_done }
--- netfs | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/netfs b/netfs index 2bcec6c..8b42cd8 100755 --- a/netfs +++ b/netfs @@ -37,7 +37,7 @@ case "$1" in $0 start ;; *) - echo "usage: $0 {start|stop|restart}" + echo "usage: $0 {start|stop|restart}" esac
# vim: set ts=2 noet:
We set $PATH in functions now, so use it. --- netfs | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/netfs b/netfs index 8b42cd8..fff8482 100755 --- a/netfs +++ b/netfs @@ -9,9 +9,9 @@ rc=0 case "$1" in start) stat_busy "Mounting Network Filesystems" - /bin/mount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs + mount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs rc=$? - /bin/mount -a -O _netdev + mount -a -O _netdev if ((rc + $? > 0)); then stat_fail else @@ -21,9 +21,9 @@ case "$1" in ;; stop) stat_busy "Unmounting Network Filesystems" - /bin/umount -a -O _netdev + umount -a -O _netdev rc=$? - /bin/umount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs + umount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs if ((rc + $? > 0)); then stat_fail else
Get rid of simple if-clauses and provide meaningfull exit code. Maybe someone wants to abort suspend to disk/ram or something if umount fails or even start this in a loop. --- netfs | 21 +++++++-------------- 1 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/netfs b/netfs index fff8482..ffda681 100755 --- a/netfs +++ b/netfs @@ -4,32 +4,24 @@ . /etc/rc.conf . /etc/rc.d/functions
-rc=0 - case "$1" in start) stat_busy "Mounting Network Filesystems" mount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs rc=$? mount -a -O _netdev - if ((rc + $? > 0)); then - stat_fail - else - add_daemon netfs - stat_done - fi + (( rc || $? )) && stat_die + add_daemon netfs + stat_done ;; stop) stat_busy "Unmounting Network Filesystems" umount -a -O _netdev rc=$? umount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs - if ((rc + $? > 0)); then - stat_fail - else - rm_daemon netfs - stat_done - fi + (( rc || $? )) && stat_die + rm_daemon netfs + stat_done ;; restart) $0 stop @@ -38,6 +30,7 @@ case "$1" in ;; *) echo "usage: $0 {start|stop|restart}" + exit 1 esac
# vim: set ts=2 noet:
Currently $NETFS is used only for fsck and mount in rc.sysinit. Since we moved it into functions, we can use it in netfs too to get rid of redundancy.
functions: * Move 'nosysfs' from $NETFS into the mount -a type list because thats obviously the only meaningfull place. * Add 'nofuse.glusterfs' to $NETFS to match the lists in netfs. * Remove all 'no'-prefixes from $NETFS to make it more useful and readable. * Add 'no'-prefixes to fsck and mount -a commands by parameter substitution.
netfs: * Instead of the literals use $NETFS from functions which contains the same types now --- functions | 6 +++--- netfs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/functions b/functions index 09655ab..ae60771 100644 --- a/functions +++ b/functions @@ -375,11 +375,11 @@ read_crypttab() {
# Filesystem functions # These can be overridden/reused for customizations like shutdown/loop-fsck. -NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs,nodavfs" +NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.glusterfs"
# Check local filesystems fsck_all() { - fsck -A -T -C$FSCK_FD -a -t "$NETFS,noopts=_netdev" $FORCEFSCK + fsck -A -T -C$FSCK_FD -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK return $? }
@@ -419,7 +419,7 @@ fsck_reboot() { }
mount_all() { - mount -a -t "$NETFS" -O no_netdev + mount -a -t "nosysfs,no${NETFS//,/,no}" -O no_netdev }
bootlogd_stop() { diff --git a/netfs b/netfs index ffda681..ea7e4eb 100755 --- a/netfs +++ b/netfs @@ -7,7 +7,7 @@ case "$1" in start) stat_busy "Mounting Network Filesystems" - mount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs + mount -a -t "$NETFS" rc=$? mount -a -O _netdev (( rc || $? )) && stat_die @@ -18,7 +18,7 @@ case "$1" in stat_busy "Unmounting Network Filesystems" umount -a -O _netdev rc=$? - umount -a -t nfs,nfs4,smbfs,codafs,ncpfs,cifs,shfs,glusterfs,fuse,fuseblk,fuse.glusterfs,davfs + umount -a -t "$NETFS" (( rc || $? )) && stat_die rm_daemon netfs stat_done
There are only two possible situations: a) /var/run is a symlink to /run: Conditional result is always 'false' even without checking /var/run/daemons (which doesn't exist). b) /var/run is a directory: Conditional result is always 'true' because any symlink was removed when cleaning /var/run.
So following changes can be made: * /var/run/daemons can be removed unconditionally because a symlink doesn't survive cleaning of /var/run anyway. * The check whether /var/run/daemons is a symlink can be dropped because it has actually no effect.
Furthermore we can refactor to use the same conditional used for cleaning /var/run because we can't create the symlink if /var/run is not a directory. --- rc.sysinit | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index 4132b8c..7357582 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -227,12 +227,12 @@ 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/.* &>/dev/null + rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.* /var/run/daemons &>/dev/null [[ ! -L /var/lock ]] && rm -rf /var/lock/* - [[ ! -L /var/run && -d /var/run ]] && find /var/run/ ! -type d -delete - [[ ! -L /var/run && ! -L /var/run/daemons ]] && - rm -rf /var/run/daemons && + if [[ ! -L /var/run && -d /var/run ]]; then + find /var/run/ ! -type d -delete ln -s /run/daemons /var/run/daemons + fi install -Tm 0664 -o root -g utmp <(:) /var/run/utmp # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix
Instead of guessing about symlinks, use stat to check whether the filesystem refered to is actually a tmpfs. Then always clean up if it isn't. --- rc.sysinit | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index 7357582..1dd3d9a 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -228,8 +228,8 @@ RANDOM_SEED=/var/lib/misc/random-seed
stat_busy "Removing Leftover Files" rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.* /var/run/daemons &>/dev/null - [[ ! -L /var/lock ]] && rm -rf /var/lock/* - if [[ ! -L /var/run && -d /var/run ]]; then + [[ -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 ln -s /run/daemons /var/run/daemons fi
On Sun, Jul 10, 2011 at 6:57 PM, Kurt J. Bosch kjb-temp-2009@alpenjodel.de wrote:
Instead of guessing about symlinks, use stat to check whether the filesystem refered to is actually a tmpfs. Then always clean up if it isn't.
This is counter intuitive. The point is that we don't want to clean when we have a symlink (as what it points to might have been created after boot). I guess the result would be the same, but I'd rather keep it as it is, unless there is a bug report.
Cheers,
Tom
Tom Gundersen, 2011-07-10 22:04:
On Sun, Jul 10, 2011 at 6:57 PM, Kurt J. Bosch kjb-temp-2009@alpenjodel.de wrote:
Instead of guessing about symlinks, use stat to check whether the filesystem refered to is actually a tmpfs. Then always clean up if it isn't.
This is counter intuitive. The point is that we don't want to clean when we have a symlink (as what it points to might have been created after boot). I guess the result would be the same, but I'd rather keep it as it is, unless there is a bug report.
Cheers,
Tom
OK to me also, as it would only make a difference in exotic/unsupported configurations AFAIKS.
No need to set $PATH any more now that is in functions --- rc.single | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/rc.single b/rc.single index 21fe3be..7a87c72 100755 --- a/rc.single +++ b/rc.single @@ -6,8 +6,6 @@ . /etc/rc.conf . /etc/rc.d/functions
-export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - run_hook single_start
if [[ $PREVLEVEL != N ]]; then
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 | 56 +++++++++++++++++++++++++++++++------------------------- 5 files changed, 49 insertions(+), 33 deletions(-)
diff --git a/functions b/functions index ae60771..58f7fa4 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 1dd3d9a..13ca0be 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 ]] || is_in_array forcefsck $(< /proc/cmdline) && 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 @@ -245,8 +250,9 @@ 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 +288,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
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
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"
mount -a -O _netdevrc=$?
(( rc || $? )) && stat_die
add_daemon netfs
stat_done
;; stop) stat_busy "Unmounting Network Filesystems" umount -a -O _netdevstat_done && add_daemon netfs || exit 1
umount -a -t "$NETFS"rc=$?
(( rc || $? )) && stat_die
rm_daemon netfs
stat_done
;; restart) $0 stopstat_done && rm_daemon netfs || exit 1
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
# If devtmpfs is used, the required RTC device already exists now # Otherwise, create whatever device is available if ! [[ -c /dev/rtc || -c /dev/rtc0 ]]; thenmodprobe -q -a rtc-cmos rtc genrtc || :
@@ -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
do_unlock() { # $1 = requested name # $2 = source devicemodprobe -q dm-crypt 2>/dev/null || :
@@ -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=$?
(( fsckret <= 1 )) && stat_done || stat_failfsck_all >|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} || fsckret=$?
-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
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).
On Sun, Jul 10, 2011 at 6:57 PM, Kurt J. Bosch kjb-temp-2009@alpenjodel.de 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.
I think this is too complicated for too little gain, especially if it will not work everywhere and has to be enabled explicitly. We should avoid being too clever I think. If we want to check for more exit statuses we should add more " || stat_fail".
-t
Tom Gundersen, 2011-07-10 22:11:
On Sun, Jul 10, 2011 at 6:57 PM, Kurt J. Bosch kjb-temp-2009@alpenjodel.de 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.
I think this is too complicated for too little gain, especially if it will not work everywhere and has to be enabled explicitly. We should avoid being too clever I think. If we want to check for more exit statuses we should add more " || stat_fail".
-t
OK here we go:
1st alternative -----------------
functions:
stat_done() { printf ... STAT_ERR=0 }
stat_fail() { printf ... STAT_ERR=1 }
stat_done() { (( STAT_ERR )) && return 0 printf ... }
rc.sysinit:
stat_busy "Removing Leftover Files" rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons || stat_fail [[ ! -L /var/lock ]] && rm -rf /var/lock/* || stat_fail if [[ ! -L /var/run && -d /var/run ]]; then find /var/run/ ! -type d -delete || stat_fail ln -s /run/daemons /var/run/daemons || stat_fail fi install -Tm 0664 -o root -g utmp <(:) /var/run/utmp || stat_fail # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix || stat_fail stat_done
2nd alternative -----------------
rc.sysinit:
stat_busy "Removing Leftover Files"; e=0 rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons || e=1 [[ ! -L /var/lock ]] && rm -rf /var/lock/* || e=1 if [[ ! -L /var/run && -d /var/run ]]; then find /var/run/ ! -type d -delete || e=1 ln -s /run/daemons /var/run/daemons || e=1 fi install -Tm 0664 -o root -g utmp <(:) /var/run/utmp || e=1 # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix || e=1 (( e )) && stat_fail || stat_done
Both look very ugly and are even more complicated IMHO.
I admit this is not really urgent as long as no bug reports arise which would suggest catching more errors.
Use correct patterns and get rid of the /dev/null redirection workaround needed when trying to remove '..'. --- rc.sysinit | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rc.sysinit b/rc.sysinit index bfaaf1b..6af105f 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -227,7 +227,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 [[ ! -L /var/lock ]] && rm -rf /var/lock/* if [[ ! -L /var/run && -d /var/run ]]; then find /var/run/ ! -type d -delete
Move it into a function to allow clean error detection of all steps performed and also to be able to reuse this in rc.single. --- functions | 14 ++++++++++++++ rc.sysinit | 13 ++----------- 2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/functions b/functions index 000ee0e..fdf30fd 100644 --- a/functions +++ b/functions @@ -417,6 +417,20 @@ mount_all() { mount -a -t "nosysfs,no${NETFS//,/,no}" -O no_netdev }
+remove_leftover() { + stat_busy "Removing Leftover Files" + rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons + [[ ! -L /var/lock ]] && rm -rf /var/lock/* + if [[ ! -L /var/run && -d /var/run ]]; then + find /var/run/ ! -type d -delete + ln -s /run/daemons /var/run/daemons + fi + install -Tm 0664 -o root -g utmp <(:) /var/run/utmp + # Keep {x,k,g}dm happy with xorg + mkdir -m 1777 /tmp/.{X11,ICE}-unix + stat_done +} + bootlogd_stop() { [[ -f /run/bootlogd.pid ]] || return 0 touch /var/log/boot diff --git a/rc.sysinit b/rc.sysinit index 6af105f..1516fba 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -226,17 +226,8 @@ RANDOM_SEED=/var/lib/misc/random-seed status "Initializing Random Seed" \ cp $RANDOM_SEED /dev/urandom
-stat_busy "Removing Leftover Files" - rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons - [[ ! -L /var/lock ]] && rm -rf /var/lock/* - if [[ ! -L /var/run && -d /var/run ]]; then - find /var/run/ ! -type d -delete - ln -s /run/daemons /var/run/daemons - fi - install -Tm 0664 -o root -g utmp <(:) /var/run/utmp - # Keep {x,k,g}dm happy with xorg - mkdir -m 1777 /tmp/.{X11,ICE}-unix -stat_done +# Remove leftover files +remove_leftover
if [[ $HOSTNAME ]]; then stat_busy "Setting Hostname: $HOSTNAME"
This avoids trouble because of stale /run/daemons/* files. --- rc.single | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/rc.single b/rc.single index 7a87c72..3527a99 100755 --- a/rc.single +++ b/rc.single @@ -23,6 +23,9 @@ if [[ $PREVLEVEL != N ]]; then
# Start/trigger UDev, load MODULES and settle UDev udevd_modprobe single + + # Removing leftover files + remove_leftover fi
run_hook single_end
Use a trap on 'ERR' to catch any error. Doing so introduces no side effects as long as we don't use 'set -E' and do a 'trap - ERR' before returning to restore what we had there before calling the function (if anything).
This avoids reporting '[DONE]' in spite of actions were done partly only.
Usecase: Some splash system hides the console messages, but is able to detect '[FAIL]' by overriding stat_fail(). --- functions | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index fdf30fd..a3c3c5e 100644 --- a/functions +++ b/functions @@ -419,6 +419,8 @@ mount_all() {
remove_leftover() { stat_busy "Removing Leftover Files" + local error=0 + trap 'error=1' ERR rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons [[ ! -L /var/lock ]] && rm -rf /var/lock/* if [[ ! -L /var/run && -d /var/run ]]; then @@ -428,7 +430,9 @@ remove_leftover() { install -Tm 0664 -o root -g utmp <(:) /var/run/utmp # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix - stat_done + trap - ERR + (( error )) && stat_fail || stat_done + return $error }
bootlogd_stop() {
Avoid overriding error condition in case any custom stat_fail returns false. --- functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index a3c3c5e..2bd6893 100644 --- a/functions +++ b/functions @@ -431,7 +431,7 @@ remove_leftover() { # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix trap - ERR - (( error )) && stat_fail || stat_done + (( error == 0 )) && stat_done || stat_fail return $error }
On Tue, Jul 12, 2011 at 10:55:19AM +0200, Kurt J. Bosch wrote:
Avoid overriding error condition in case any custom stat_fail returns false.
functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index a3c3c5e..2bd6893 100644 --- a/functions +++ b/functions @@ -431,7 +431,7 @@ remove_leftover() { # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix trap - ERR
- (( error )) && stat_fail || stat_done
- (( error == 0 )) && stat_done || stat_fail return $error
}
-- 1.7.1
This is a bug fix patch on top of an unmerged patch...
Dave Reisner, 2011-07-12 12:22:
On Tue, Jul 12, 2011 at 10:55:19AM +0200, Kurt J. Bosch wrote:
Avoid overriding error condition in case any custom stat_fail returns false.
functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index a3c3c5e..2bd6893 100644 --- a/functions +++ b/functions @@ -431,7 +431,7 @@ remove_leftover() { # Keep {x,k,g}dm happy with xorg mkdir -m 1777 /tmp/.{X11,ICE}-unix trap - ERR
- (( error ))&& stat_fail || stat_done
- (( error == 0 ))&& stat_done || stat_fail return $error }
-- 1.7.1
This is a bug fix patch on top of an unmerged patch...
OK. Squashed in the new thread.
Simplify conditionals a bit to make this more readable.
Make this a bit more readable and uniform. --- functions | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/functions b/functions index 2bd6893..77387cb 100644 --- a/functions +++ b/functions @@ -506,22 +506,20 @@ set_consolefont() { [[ $CONSOLEFONT ]] || return 0 stat_busy "Loading Console Font: $CONSOLEFONT" #CONSOLEMAP in UTF-8 shouldn't be used - [[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" + [[ ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ $CONSOLEFONT -C ${i} &>/dev/null done if (( $? )); then - stat_fail + false elif [[ $CONSOLEMAP ]]; then cat <<"EOF" >>/etc/profile.d/locale.sh if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi EOF - stat_done - else - stat_done fi + (( $? == 0 )) && stat_done || stat_fail }
# Source additional functions at the end to allow overrides
--- functions | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/functions b/functions index 77387cb..722098d 100644 --- a/functions +++ b/functions @@ -512,13 +512,13 @@ set_consolefont() { setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ $CONSOLEFONT -C ${i} &>/dev/null done - if (( $? )); then - false - elif [[ $CONSOLEMAP ]]; then - cat <<"EOF" >>/etc/profile.d/locale.sh + if (( $? )); then + false + elif [[ $CONSOLEMAP ]]; then + cat <<"EOF" >>/etc/profile.d/locale.sh if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi EOF - fi + fi (( $? == 0 )) && stat_done || stat_fail }
The rules should be:
* Use quotes when literal strings are involved. * Use quotes when ever using a substitution which might produce blanks as a possitional parameter unless word splitting is intended. * Don't use quotes for substitutions where _clearly_ not needed. That is within '[[ ]]', assignments and 'case ... in' (where no word splitting is performed) and also when using local variables which _obviously_ don't contain blanks. --- functions | 50 +++++++++++++++++++++++++------------------------- rc.sysinit | 22 +++++++++++----------- 2 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/functions b/functions index 722098d..bdb8529 100644 --- a/functions +++ b/functions @@ -20,9 +20,9 @@ calc_columns () { USECOLOR="" elif [[ -t 0 ]]; then # stty will fail when stdin isn't a terminal - STAT_COL="$(stty size)" + STAT_COL=$(stty size) # stty gives "rows cols"; strip the rows number, we just want columns - STAT_COL="${STAT_COL##* }" + STAT_COL=${STAT_COL##* } elif tput cols &>/dev/null; then # is /usr/share/terminfo already mounted, and TERM recognized? STAT_COL=$(tput cols) @@ -50,7 +50,7 @@ calc_columns () { calc_columns
# disable colors on broken terminals -TERM_COLORS="$(tput colors 2>/dev/null)" +TERM_COLORS=$(tput colors 2>/dev/null) if (( $? != 3 )); then case $TERM_COLORS in *[!0-9]*) USECOLOR="";; @@ -76,16 +76,16 @@ fi # set colors if [[ $USECOLOR = [yY][eE][sS] ]]; then if tput setaf 0 &>/dev/null; then - C_CLEAR="$(tput sgr0)" # clear text - C_MAIN="${C_CLEAR}$(tput bold)" # main text - C_OTHER="${C_MAIN}$(tput setaf 4)" # prefix & brackets - C_SEPARATOR="${C_MAIN}$(tput setaf 0)" # separator - C_BUSY="${C_CLEAR}$(tput setaf 6)" # busy - C_FAIL="${C_MAIN}$(tput setaf 1)" # failed - C_DONE="${C_MAIN}" # completed - C_BKGD="${C_MAIN}$(tput setaf 5)" # backgrounded - C_H1="${C_MAIN}" # highlight text 1 - C_H2="${C_MAIN}$(tput setaf 6)" # highlight text 2 + C_CLEAR=$(tput sgr0) # clear text + C_MAIN=${C_CLEAR}$(tput bold) # main text + C_OTHER=${C_MAIN}$(tput setaf 4) # prefix & brackets + C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator + C_BUSY=${C_CLEAR}$(tput setaf 6) # busy + C_FAIL=${C_MAIN}$(tput setaf 1) # failed + C_DONE=${C_MAIN} # completed + C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded + C_H1=${C_MAIN} # highlight text 1 + C_H2=${C_MAIN}$(tput setaf 6) # highlight text 2 else C_CLEAR="\e[m" # clear text C_MAIN="\e[;1m" # main text @@ -93,9 +93,9 @@ if [[ $USECOLOR = [yY][eE][sS] ]]; then C_SEPARATOR="\e[1;30m" # separator C_BUSY="\e[;36m" # busy C_FAIL="\e[1;31m" # failed - C_DONE="${C_MAIN}" # completed + C_DONE=${C_MAIN} # completed C_BKGD="\e[1;35m" # backgrounded - C_H1="${C_MAIN}" # highlight text 1 + C_H1=${C_MAIN} # highlight text 1 C_H2="\e[1;36m" # highlight text 2 fi fi @@ -198,7 +198,7 @@ have_daemon() { ck_autostart() { local d for d in "${DAEMONS[@]}"; do - [[ "$1" = ${d#@} ]] && return 1 + [[ $1 = ${d#@} ]] && return 1 done return 0 } @@ -247,11 +247,11 @@ get_pid() {
# Check if PID-file $1 is still the active PID-file for command $2 ck_pidfile() { - if [[ -f "$1" ]]; then + if [[ -f $1 ]]; then local fpid ppid read -r fpid <"$1" - ppid=$(get_pid $2) - [[ "$fpid" = "$ppid" ]] && return 0 + ppid=$(get_pid "$2") + [[ $fpid = $ppid ]] && return 0 fi return 1 } @@ -279,7 +279,7 @@ stop_all_daemons() { local i for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do [[ ${DAEMONS[i]} = '!'* ]] && continue - ck_daemon ${DAEMONS[i]#@} || stop_daemon ${DAEMONS[i]#@} + ck_daemon "${DAEMONS[i]#@}" || stop_daemon "${DAEMONS[i]#@}" done }
@@ -325,7 +325,7 @@ udevd_modprobe() { status "Loading Modules" modprobe -ab "${MODULES[@]}"
status "Waiting for UDev uevents to be processed" \ - udevadm settle --timeout=${UDEV_TIMEOUT:-30} + udevadm settle --timeout="${UDEV_TIMEOUT:-30}"
run_hook "$1_udevsettled"
@@ -374,7 +374,7 @@ NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.g
# Check local filesystems fsck_all() { - fsck -A -T -C$FSCK_FD -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK + fsck -A -T -C"$FSCK_FD" -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK return $? }
@@ -486,7 +486,7 @@ if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
add_hook() { [[ $1 && $2 ]] || return 1 - hook_funcs["$1"]+=" $2" + hook_funcs[$1]+=" $2" }
run_hook() { @@ -509,8 +509,8 @@ set_consolefont() { [[ ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do - setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ - $CONSOLEFONT -C ${i} &>/dev/null + setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \ + "$CONSOLEFONT" -C ${i} &>/dev/null done if (( $? )); then false diff --git a/rc.sysinit b/rc.sysinit index 1516fba..839a787 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -96,14 +96,14 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then # $3 = password # $4 = options stat_append "${1}.." - local open=create a="$1" b="$2" failed=0 + local open=create a=$1 b=$2 failed=0 # Ordering of options is different if you are using LUKS vs. not. # Use ugly swizzling to deal with it. # isLuks only gives an exit code but no output to stdout or stderr. if $CS isLuks "$2" 2>/dev/null; then open=luksOpen - a="$2" - b="$1" + a=$2 + b=$1 fi case $3 in SWAP) @@ -123,13 +123,13 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi if (( _overwriteokay == 0 )); then false - elif $CS -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then + elif $CS -d /dev/urandom "$4" $open "$a" "$b" >/dev/null; then stat_append "creating swapspace.." - mkswap -f -L $1 /dev/mapper/$1 >/dev/null + mkswap -f -L $1 /dev/mapper/"$1" >/dev/null fi;; ASK) printf "\nOpening '$1' volume:\n" - $CS $4 $open "$a" "$b" < /dev/console;; + $CS "$4" $open "$a" "$b" < /dev/console;; /dev*) local ckdev=${3%%:*} local cka=${3#*:} @@ -151,13 +151,13 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then # cka is numeric: cka=offset, ckb=length dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb} >/dev/null 2>&1;; esac - $CS -d ${ckfile} $4 $open "$a" "$b" >/dev/null + $CS -d ${ckfile} "$4" $open "$a" "$b" >/dev/null dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc >/dev/null 2>&1 rm ${ckfile};; /*) - $CS -d "$3" $4 $open "$a" "$b" >/dev/null;; + $CS -d "$3" "$4" $open "$a" "$b" >/dev/null;; *) - echo "$3" | $CS $4 $open "$a" "$b" >/dev/null;; + echo "$3" | $CS "$4" $open "$a" "$b" >/dev/null;; esac if (( $? )); then failed=1 @@ -179,7 +179,7 @@ declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems" - fsck_all >|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} + fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}" declare -r fsckret=$? (( fsckret <= 1 )) && stat_done || stat_fail else @@ -261,7 +261,7 @@ else stat_done fi [[ $KEYMAP ]] && - status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP + status "Loading Keyboard Map: $KEYMAP" loadkeys -q "$KEYMAP"
# Set console font if required set_consolefont
The rules should be:
* Use quotes when literal strings are involved. * Use quotes when ever using a substitution which might produce blanks as a possitional parameter unless word splitting is intended. * Don't use quotes for substitutions where _clearly_ not needed. That is within '[[ ]]', assignments and 'case ... in' (where no word splitting is performed) and also when using local variables which _obviously_ don't contain blanks. --- functions | 50 +++++++++++++++++++++++++------------------------- rc.sysinit | 10 +++++----- 2 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/functions b/functions index 722098d..ddd9585 100644 --- a/functions +++ b/functions @@ -20,9 +20,9 @@ calc_columns () { USECOLOR="" elif [[ -t 0 ]]; then # stty will fail when stdin isn't a terminal - STAT_COL="$(stty size)" + STAT_COL=$(stty size) # stty gives "rows cols"; strip the rows number, we just want columns - STAT_COL="${STAT_COL##* }" + STAT_COL=${STAT_COL##* } elif tput cols &>/dev/null; then # is /usr/share/terminfo already mounted, and TERM recognized? STAT_COL=$(tput cols) @@ -50,7 +50,7 @@ calc_columns () { calc_columns
# disable colors on broken terminals -TERM_COLORS="$(tput colors 2>/dev/null)" +TERM_COLORS=$(tput colors 2>/dev/null) if (( $? != 3 )); then case $TERM_COLORS in *[!0-9]*) USECOLOR="";; @@ -76,16 +76,16 @@ fi # set colors if [[ $USECOLOR = [yY][eE][sS] ]]; then if tput setaf 0 &>/dev/null; then - C_CLEAR="$(tput sgr0)" # clear text - C_MAIN="${C_CLEAR}$(tput bold)" # main text - C_OTHER="${C_MAIN}$(tput setaf 4)" # prefix & brackets - C_SEPARATOR="${C_MAIN}$(tput setaf 0)" # separator - C_BUSY="${C_CLEAR}$(tput setaf 6)" # busy - C_FAIL="${C_MAIN}$(tput setaf 1)" # failed - C_DONE="${C_MAIN}" # completed - C_BKGD="${C_MAIN}$(tput setaf 5)" # backgrounded - C_H1="${C_MAIN}" # highlight text 1 - C_H2="${C_MAIN}$(tput setaf 6)" # highlight text 2 + C_CLEAR=$(tput sgr0) # clear text + C_MAIN=${C_CLEAR}$(tput bold) # main text + C_OTHER=${C_MAIN}$(tput setaf 4) # prefix & brackets + C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator + C_BUSY=${C_CLEAR}$(tput setaf 6) # busy + C_FAIL=${C_MAIN}$(tput setaf 1) # failed + C_DONE=${C_MAIN} # completed + C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded + C_H1=${C_MAIN} # highlight text 1 + C_H2=${C_MAIN}$(tput setaf 6) # highlight text 2 else C_CLEAR="\e[m" # clear text C_MAIN="\e[;1m" # main text @@ -93,9 +93,9 @@ if [[ $USECOLOR = [yY][eE][sS] ]]; then C_SEPARATOR="\e[1;30m" # separator C_BUSY="\e[;36m" # busy C_FAIL="\e[1;31m" # failed - C_DONE="${C_MAIN}" # completed + C_DONE=${C_MAIN} # completed C_BKGD="\e[1;35m" # backgrounded - C_H1="${C_MAIN}" # highlight text 1 + C_H1=${C_MAIN} # highlight text 1 C_H2="\e[1;36m" # highlight text 2 fi fi @@ -198,7 +198,7 @@ have_daemon() { ck_autostart() { local d for d in "${DAEMONS[@]}"; do - [[ "$1" = ${d#@} ]] && return 1 + [[ $1 = ${d#@} ]] && return 1 done return 0 } @@ -247,11 +247,11 @@ get_pid() {
# Check if PID-file $1 is still the active PID-file for command $2 ck_pidfile() { - if [[ -f "$1" ]]; then + if [[ -f $1 ]]; then local fpid ppid read -r fpid <"$1" - ppid=$(get_pid $2) - [[ "$fpid" = "$ppid" ]] && return 0 + ppid=$(get_pid "$2") + [[ $fpid = $ppid ]] && return 0 fi return 1 } @@ -279,7 +279,7 @@ stop_all_daemons() { local i for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do [[ ${DAEMONS[i]} = '!'* ]] && continue - ck_daemon ${DAEMONS[i]#@} || stop_daemon ${DAEMONS[i]#@} + ck_daemon "${DAEMONS[i]#@}" || stop_daemon "${DAEMONS[i]#@}" done }
@@ -325,7 +325,7 @@ udevd_modprobe() { status "Loading Modules" modprobe -ab "${MODULES[@]}"
status "Waiting for UDev uevents to be processed" \ - udevadm settle --timeout=${UDEV_TIMEOUT:-30} + udevadm settle --timeout="${UDEV_TIMEOUT:-30}"
run_hook "$1_udevsettled"
@@ -374,7 +374,7 @@ NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.g
# Check local filesystems fsck_all() { - fsck -A -T -C$FSCK_FD -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK + fsck -A -T -C"$FSCK_FD" -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK return $? }
@@ -486,7 +486,7 @@ if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
add_hook() { [[ $1 && $2 ]] || return 1 - hook_funcs["$1"]+=" $2" + hook_funcs[$1]+=" $2" }
run_hook() { @@ -509,8 +509,8 @@ set_consolefont() { [[ ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do - setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ - $CONSOLEFONT -C ${i} &>/dev/null + setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \ + "$CONSOLEFONT" -C ${i} &>/dev/null done if (( $? )); then false diff --git a/rc.sysinit b/rc.sysinit index 1516fba..08ad906 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -96,14 +96,14 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then # $3 = password # $4 = options stat_append "${1}.." - local open=create a="$1" b="$2" failed=0 + local open=create a=$1 b=$2 failed=0 # Ordering of options is different if you are using LUKS vs. not. # Use ugly swizzling to deal with it. # isLuks only gives an exit code but no output to stdout or stderr. if $CS isLuks "$2" 2>/dev/null; then open=luksOpen - a="$2" - b="$1" + a=$2 + b=$1 fi case $3 in SWAP) @@ -179,7 +179,7 @@ declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems" - fsck_all >|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout} + fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}" declare -r fsckret=$? (( fsckret <= 1 )) && stat_done || stat_fail else @@ -261,7 +261,7 @@ else stat_done fi [[ $KEYMAP ]] && - status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP + status "Loading Keyboard Map: $KEYMAP" loadkeys -q "$KEYMAP"
# Set console font if required set_consolefont
On Tue, Jul 12, 2011 at 10:58:36AM +0200, Kurt J. Bosch wrote:
The rules should be:
- Use quotes when literal strings are involved.
- Use quotes when ever using a substitution which might produce blanks as a possitional parameter unless word splitting is intended.
- Don't use quotes for substitutions where _clearly_ not needed. That is within '[[ ]]', assignments and 'case ... in' (where no word splitting is performed) and also when using local variables which _obviously_ don't contain blanks.
The RHS of a bash test is subject to glob matching and should almost always be quoted.
$ pattern=foo* $ [[ foobar = $pattern ]]; echo $? 0 $ [[ foobar = "$pattern" ]]; echo $? 1
So this isn't really black and white. Fortunately, this doesn't appear to be an issue.
Other comments inlined.
functions | 50 +++++++++++++++++++++++++------------------------- rc.sysinit | 22 +++++++++++----------- 2 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/functions b/functions index 722098d..bdb8529 100644 --- a/functions +++ b/functions @@ -20,9 +20,9 @@ calc_columns () { USECOLOR="" elif [[ -t 0 ]]; then # stty will fail when stdin isn't a terminal
STAT_COL="$(stty size)"
# stty gives "rows cols"; strip the rows number, we just want columnsSTAT_COL=$(stty size)
STAT_COL="${STAT_COL##* }"
elif tput cols &>/dev/null; then # is /usr/share/terminfo already mounted, and TERM recognized? STAT_COL=$(tput cols)STAT_COL=${STAT_COL##* }
@@ -50,7 +50,7 @@ calc_columns () { calc_columns
# disable colors on broken terminals -TERM_COLORS="$(tput colors 2>/dev/null)" +TERM_COLORS=$(tput colors 2>/dev/null) if (( $? != 3 )); then case $TERM_COLORS in *[!0-9]*) USECOLOR="";; @@ -76,16 +76,16 @@ fi # set colors if [[ $USECOLOR = [yY][eE][sS] ]]; then if tput setaf 0 &>/dev/null; then
C_CLEAR="$(tput sgr0)" # clear text
C_MAIN="${C_CLEAR}$(tput bold)" # main text
C_OTHER="${C_MAIN}$(tput setaf 4)" # prefix & brackets
C_SEPARATOR="${C_MAIN}$(tput setaf 0)" # separator
C_BUSY="${C_CLEAR}$(tput setaf 6)" # busy
C_FAIL="${C_MAIN}$(tput setaf 1)" # failed
C_DONE="${C_MAIN}" # completed
C_BKGD="${C_MAIN}$(tput setaf 5)" # backgrounded
C_H1="${C_MAIN}" # highlight text 1
C_H2="${C_MAIN}$(tput setaf 6)" # highlight text 2
C_CLEAR=$(tput sgr0) # clear text
C_MAIN=${C_CLEAR}$(tput bold) # main text
C_OTHER=${C_MAIN}$(tput setaf 4) # prefix & brackets
C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator
C_BUSY=${C_CLEAR}$(tput setaf 6) # busy
C_FAIL=${C_MAIN}$(tput setaf 1) # failed
C_DONE=${C_MAIN} # completed
C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded
C_H1=${C_MAIN} # highlight text 1
else C_CLEAR="\e[m" # clear text C_MAIN="\e[;1m" # main textC_H2=${C_MAIN}$(tput setaf 6) # highlight text 2
@@ -93,9 +93,9 @@ if [[ $USECOLOR = [yY][eE][sS] ]]; then C_SEPARATOR="\e[1;30m" # separator C_BUSY="\e[;36m" # busy C_FAIL="\e[1;31m" # failed
C_DONE="${C_MAIN}" # completed
C_BKGD="\e[1;35m" # backgroundedC_DONE=${C_MAIN} # completed
C_H1="${C_MAIN}" # highlight text 1
C_H2="\e[1;36m" # highlight text 2 fiC_H1=${C_MAIN} # highlight text 1
fi @@ -198,7 +198,7 @@ have_daemon() { ck_autostart() { local d for d in "${DAEMONS[@]}"; do
[[ "$1" = ${d#@} ]] && return 1
done return 0[[ $1 = ${d#@} ]] && return 1
} @@ -247,11 +247,11 @@ get_pid() {
# Check if PID-file $1 is still the active PID-file for command $2 ck_pidfile() {
- if [[ -f "$1" ]]; then
- if [[ -f $1 ]]; then local fpid ppid read -r fpid <"$1"
ppid=$(get_pid $2)
[[ "$fpid" = "$ppid" ]] && return 0
ppid=$(get_pid "$2")
fi return 1[[ $fpid = $ppid ]] && return 0
} @@ -279,7 +279,7 @@ stop_all_daemons() { local i for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do [[ ${DAEMONS[i]} = '!'* ]] && continue
ck_daemon ${DAEMONS[i]#@} || stop_daemon ${DAEMONS[i]#@}
doneck_daemon "${DAEMONS[i]#@}" || stop_daemon "${DAEMONS[i]#@}"
}
@@ -325,7 +325,7 @@ udevd_modprobe() { status "Loading Modules" modprobe -ab "${MODULES[@]}"
status "Waiting for UDev uevents to be processed" \
udevadm settle --timeout=${UDEV_TIMEOUT:-30}
udevadm settle --timeout="${UDEV_TIMEOUT:-30}"
Why does this warrant quoting? passing --timeout= is harmless. If a user sets anything but a number here it's a syntax error, and udevadm will, furthermore, ignore the argument that it doesn't understand when multiple words are assigned.
run_hook "$1_udevsettled"
@@ -374,7 +374,7 @@ NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.g
# Check local filesystems fsck_all() {
- fsck -A -T -C$FSCK_FD -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK
- fsck -A -T -C"$FSCK_FD" -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK return $?
}
@@ -486,7 +486,7 @@ if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
add_hook() { [[ $1 && $2 ]] || return 1
hook_funcs["$1"]+=" $2"
hook_funcs[$1]+=" $2"
}
run_hook() {
@@ -509,8 +509,8 @@ set_consolefont() { [[ ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do
setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \
$CONSOLEFONT -C ${i} &>/dev/null
setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \
done if (( $? )); then false"$CONSOLEFONT" -C ${i} &>/dev/null
diff --git a/rc.sysinit b/rc.sysinit index 1516fba..839a787 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -96,14 +96,14 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then # $3 = password # $4 = options stat_append "${1}.."
local open=create a="$1" b="$2" failed=0
local open=create a=$1 b=$2 failed=0 # Ordering of options is different if you are using LUKS vs. not. # Use ugly swizzling to deal with it. # isLuks only gives an exit code but no output to stdout or stderr. if $CS isLuks "$2" 2>/dev/null; then open=luksOpen
a="$2"
b="$1"
a=$2
b=$1 fi case $3 in SWAP)
@@ -123,13 +123,13 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then fi if (( _overwriteokay == 0 )); then false
elif $CS -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then
elif $CS -d /dev/urandom "$4" $open "$a" "$b" >/dev/null; then stat_append "creating swapspace.."
mkswap -f -L $1 /dev/mapper/$1 >/dev/null
mkswap -f -L $1 /dev/mapper/"$1" >/dev/null fi;; ASK) printf "\nOpening '$1' volume:\n"
$CS $4 $open "$a" "$b" < /dev/console;;
$CS "$4" $open "$a" "$b" < /dev/console;; /dev*) local ckdev=${3%%:*} local cka=${3#*:}
@@ -151,13 +151,13 @@ if [[ -f /etc/crypttab && $CS ]] && grep -q ^[^#] /etc/crypttab; then # cka is numeric: cka=offset, ckb=length dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb} >/dev/null 2>&1;; esac
$CS -d ${ckfile} $4 $open "$a" "$b" >/dev/null
$CS -d ${ckfile} "$4" $open "$a" "$b" >/dev/null dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc >/dev/null 2>&1 rm ${ckfile};; /*)
$CS -d "$3" $4 $open "$a" "$b" >/dev/null;;
$CS -d "$3" "$4" $open "$a" "$b" >/dev/null;; *)
echo "$3" | $CS $4 $open "$a" "$b" >/dev/null;;
echo "$3" | $CS "$4" $open "$a" "$b" >/dev/null;; esac if (( $? )); then failed=1
@@ -179,7 +179,7 @@ declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems"
fsck_all >|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout}
declare -r fsckret=$? (( fsckret <= 1 )) && stat_done || stat_failfsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}"
else @@ -261,7 +261,7 @@ else stat_done fi [[ $KEYMAP ]] &&
- status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP
- status "Loading Keyboard Map: $KEYMAP" loadkeys -q "$KEYMAP"
KEYMAP might be multiple words, intentionally, to load multiple keymaps. We cannot quote this.
https://bugs.archlinux.org/task/23373
# Set console font if required set_consolefont -- 1.7.1
Dave Reisner, 2011-07-12 12:19:
On Tue, Jul 12, 2011 at 10:58:36AM +0200, Kurt J. Bosch wrote:
The rules should be:
- Use quotes when literal strings are involved.
- Use quotes when ever using a substitution which might produce blanks as a possitional parameter unless word splitting is intended.
- Don't use quotes for substitutions where _clearly_ not needed. That is within '[[ ]]', assignments and 'case ... in' (where no word splitting is performed) and also when using local variables which _obviously_ don't contain blanks.
The RHS of a bash test is subject to glob matching and should almost always be quoted.
$ pattern=foo* $ [[ foobar = $pattern ]]; echo $? 0 $ [[ foobar = "$pattern" ]]; echo $? 1
So this isn't really black and white. Fortunately, this doesn't appear to be an issue.
Good catch. Fixed this in the new thread together with those below to avoid this will ever be forgotten.
Other comments inlined.
functions | 50 +++++++++++++++++++++++++------------------------- rc.sysinit | 22 +++++++++++----------- 2 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/functions b/functions index 722098d..bdb8529 100644 --- a/functions +++ b/functions @@ -20,9 +20,9 @@ calc_columns () { USECOLOR="" elif [[ -t 0 ]]; then # stty will fail when stdin isn't a terminal
STAT_COL="$(stty size)"
# stty gives "rows cols"; strip the rows number, we just want columnsSTAT_COL=$(stty size)
STAT_COL="${STAT_COL##* }"
elif tput cols&>/dev/null; then # is /usr/share/terminfo already mounted, and TERM recognized? STAT_COL=$(tput cols)STAT_COL=${STAT_COL##* }
@@ -50,7 +50,7 @@ calc_columns () { calc_columns
# disable colors on broken terminals -TERM_COLORS="$(tput colors 2>/dev/null)" +TERM_COLORS=$(tput colors 2>/dev/null) if (( $? != 3 )); then case $TERM_COLORS in *[!0-9]*) USECOLOR="";; @@ -76,16 +76,16 @@ fi # set colors if [[ $USECOLOR = [yY][eE][sS] ]]; then if tput setaf 0&>/dev/null; then
C_CLEAR="$(tput sgr0)" # clear text
C_MAIN="${C_CLEAR}$(tput bold)" # main text
C_OTHER="${C_MAIN}$(tput setaf 4)" # prefix& brackets
C_SEPARATOR="${C_MAIN}$(tput setaf 0)" # separator
C_BUSY="${C_CLEAR}$(tput setaf 6)" # busy
C_FAIL="${C_MAIN}$(tput setaf 1)" # failed
C_DONE="${C_MAIN}" # completed
C_BKGD="${C_MAIN}$(tput setaf 5)" # backgrounded
C_H1="${C_MAIN}" # highlight text 1
C_H2="${C_MAIN}$(tput setaf 6)" # highlight text 2
C_CLEAR=$(tput sgr0) # clear text
C_MAIN=${C_CLEAR}$(tput bold) # main text
C_OTHER=${C_MAIN}$(tput setaf 4) # prefix& brackets
C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator
C_BUSY=${C_CLEAR}$(tput setaf 6) # busy
C_FAIL=${C_MAIN}$(tput setaf 1) # failed
C_DONE=${C_MAIN} # completed
C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded
C_H1=${C_MAIN} # highlight text 1
else C_CLEAR="\e[m" # clear text C_MAIN="\e[;1m" # main textC_H2=${C_MAIN}$(tput setaf 6) # highlight text 2
@@ -93,9 +93,9 @@ if [[ $USECOLOR = [yY][eE][sS] ]]; then C_SEPARATOR="\e[1;30m" # separator C_BUSY="\e[;36m" # busy C_FAIL="\e[1;31m" # failed
C_DONE="${C_MAIN}" # completed
C_BKGD="\e[1;35m" # backgroundedC_DONE=${C_MAIN} # completed
C_H1="${C_MAIN}" # highlight text 1
C_H2="\e[1;36m" # highlight text 2 fi fiC_H1=${C_MAIN} # highlight text 1
@@ -198,7 +198,7 @@ have_daemon() { ck_autostart() { local d for d in "${DAEMONS[@]}"; do
[[ "$1" = ${d#@} ]]&& return 1
done return 0 }[[ $1 = ${d#@} ]]&& return 1
@@ -247,11 +247,11 @@ get_pid() {
# Check if PID-file $1 is still the active PID-file for command $2 ck_pidfile() {
- if [[ -f "$1" ]]; then
- if [[ -f $1 ]]; then local fpid ppid read -r fpid<"$1"
ppid=$(get_pid $2)
[[ "$fpid" = "$ppid" ]]&& return 0
ppid=$(get_pid "$2")
fi return 1 }[[ $fpid = $ppid ]]&& return 0
@@ -279,7 +279,7 @@ stop_all_daemons() { local i for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do [[ ${DAEMONS[i]} = '!'* ]]&& continue
ck_daemon ${DAEMONS[i]#@} || stop_daemon ${DAEMONS[i]#@}
done }ck_daemon "${DAEMONS[i]#@}" || stop_daemon "${DAEMONS[i]#@}"
@@ -325,7 +325,7 @@ udevd_modprobe() { status "Loading Modules" modprobe -ab "${MODULES[@]}"
status "Waiting for UDev uevents to be processed" \
udevadm settle --timeout=${UDEV_TIMEOUT:-30}
udevadm settle --timeout="${UDEV_TIMEOUT:-30}"
Why does this warrant quoting? passing --timeout= is harmless. If a user sets anything but a number here it's a syntax error, and udevadm will, furthermore, ignore the argument that it doesn't understand when multiple words are assigned.
OK. You convinced me.
run_hook "$1_udevsettled"
@@ -374,7 +374,7 @@ NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.g
# Check local filesystems fsck_all() {
- fsck -A -T -C$FSCK_FD -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK
- fsck -A -T -C"$FSCK_FD" -a -t "no${NETFS//,/,no},noopts=_netdev" $FORCEFSCK return $? }
@@ -486,7 +486,7 @@ if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
add_hook() { [[ $1&& $2 ]] || return 1
hook_funcs["$1"]+=" $2"
hook_funcs[$1]+=" $2"
}
run_hook() {
@@ -509,8 +509,8 @@ set_consolefont() { [[ ${LOCALE,,} =~ utf ]]&& CONSOLEMAP="" local i for i in /dev/tty[0-9]*; do
setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \
$CONSOLEFONT -C ${i}&>/dev/null
setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \
done if (( $? )); then false"$CONSOLEFONT" -C ${i}&>/dev/null
diff --git a/rc.sysinit b/rc.sysinit index 1516fba..839a787 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -96,14 +96,14 @@ if [[ -f /etc/crypttab&& $CS ]]&& grep -q ^[^#] /etc/crypttab; then # $3 = password # $4 = options stat_append "${1}.."
local open=create a="$1" b="$2" failed=0
local open=create a=$1 b=$2 failed=0 # Ordering of options is different if you are using LUKS vs. not. # Use ugly swizzling to deal with it. # isLuks only gives an exit code but no output to stdout or stderr. if $CS isLuks "$2" 2>/dev/null; then open=luksOpen
a="$2"
b="$1"
a=$2
b=$1 fi case $3 in SWAP)
@@ -123,13 +123,13 @@ if [[ -f /etc/crypttab&& $CS ]]&& grep -q ^[^#] /etc/crypttab; then fi if (( _overwriteokay == 0 )); then false
elif $CS -d /dev/urandom $4 $open "$a" "$b">/dev/null; then
elif $CS -d /dev/urandom "$4" $open "$a" "$b">/dev/null; then stat_append "creating swapspace.."
mkswap -f -L $1 /dev/mapper/$1>/dev/null
mkswap -f -L $1 /dev/mapper/"$1">/dev/null fi;; ASK) printf "\nOpening '$1' volume:\n"
$CS $4 $open "$a" "$b"< /dev/console;;
$CS "$4" $open "$a" "$b"< /dev/console;; /dev*) local ckdev=${3%%:*} local cka=${3#*:}
@@ -151,13 +151,13 @@ if [[ -f /etc/crypttab&& $CS ]]&& grep -q ^[^#] /etc/crypttab; then # cka is numeric: cka=offset, ckb=length dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb}>/dev/null 2>&1;; esac
$CS -d ${ckfile} $4 $open "$a" "$b">/dev/null
$CS -d ${ckfile} "$4" $open "$a" "$b">/dev/null dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc>/dev/null 2>&1 rm ${ckfile};; /*)
$CS -d "$3" $4 $open "$a" "$b">/dev/null;;
$CS -d "$3" "$4" $open "$a" "$b">/dev/null;; *)
echo "$3" | $CS $4 $open "$a" "$b">/dev/null;;
echo "$3" | $CS "$4" $open "$a" "$b">/dev/null;; esac if (( $? )); then failed=1
@@ -179,7 +179,7 @@ declare -r FORCEFSCK run_hook sysinit_prefsck if [[ -x $(type -P fsck) ]]; then stat_busy "Checking Filesystems"
fsck_all>|${FSCK_OUT:-/dev/stdout} 2>|${FSCK_ERR:-/dev/stdout}
declare -r fsckret=$? (( fsckret<= 1 ))&& stat_done || stat_fail elsefsck_all>|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}"
@@ -261,7 +261,7 @@ else stat_done fi [[ $KEYMAP ]]&&
- status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP
- status "Loading Keyboard Map: $KEYMAP" loadkeys -q "$KEYMAP"
KEYMAP might be multiple words, intentionally, to load multiple keymaps. We cannot quote this.
Oops, thank you for clarifying this.
# Set console font if required set_consolefont -- 1.7.1
--- functions | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/functions b/functions index bdb8529..1414ac8 100644 --- a/functions +++ b/functions @@ -39,7 +39,7 @@ calc_columns () { if [[ -t 1 ]]; then SAVE_POSITION="\e[s" RESTORE_POSITION="\e[u" - DEL_TEXT="\e[$(($STAT_COL+4))G" + DEL_TEXT="\e[$((STAT_COL+4))G" else SAVE_POSITION="" RESTORE_POSITION="" @@ -158,7 +158,7 @@ status() { shift "$@" &>/dev/null local ret=$? - (( $ret == 0 )) && stat_done || stat_fail + (( ret == 0 )) && stat_done || stat_fail return $ret }
--- functions | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/functions b/functions index 1414ac8..6d4ec05 100644 --- a/functions +++ b/functions @@ -39,7 +39,7 @@ calc_columns () { if [[ -t 1 ]]; then SAVE_POSITION="\e[s" RESTORE_POSITION="\e[u" - DEL_TEXT="\e[$((STAT_COL+4))G" + DEL_TEXT="\e[$(( STAT_COL + 4 ))G" else SAVE_POSITION="" RESTORE_POSITION=""
arch-projects@lists.archlinux.org