Split out reading /etc/crypttab and procssing the individual lines into their own helper functions, and bashify the resulting shorter code. Processing this file is still ugly, though. :( --- functions | 43 +++++++++++++++++-- rc.shutdown | 36 +++++------------ rc.sysinit | 131 ++++++++++++++++++---------------------------------------- 3 files changed, 90 insertions(+), 120 deletions(-) diff --git a/functions b/functions index bf6ed45..9ec8b5e 100644 --- a/functions +++ b/functions @@ -232,6 +232,40 @@ kill_everything() { run_hook single_postkillall } +activate_vgs() { + [[ $USELVM =~ yes|YES && -x /sbin/lvm && -d /sys/block ]] || return + # Kernel 2.6.x, LVM2 groups + /sbin/modprobe -q dm-mod 2>/dev/null + stat_busy "Activating LVM2 groups" + if /sbin/lvm vgchange --ignorelockingfailure -a y >/dev/null; then + stat_done + else + stat_fail + fi +} + +# Arch cryptsetup packages traditionally contained the binaries +# /usr/sbin/cryptsetup +# /sbin/cryptsetup.static +# By default, initscripts used the /sbin/cryptsetup.static. +# Newer packages will only have /sbin/cryptsetup and no static binary +# This ensures maximal compatibility with the old and new layout +for CS in /sbin/cryptsetup /usr/sbin/cryptsetup \ + /sbin/cryptsetup.static ''; do + [[ -x $CS ]] && break +done + +read_crypttab() { + # $1 = function to call with the split out line from the crypttab + local line nspo failed=0 + while read line; do + [[ $line && ${line:0:1} != '#' ]] || continue + eval nspo=("${line%#*}") + $1 "${nspo[@]}" || failed=1 + done < /etc/crypttab + return $failed +} + ############################### # Custom hooks in initscripts # ############################### @@ -278,7 +312,7 @@ run_hook() { [[ $1 ]] || return 1 local func for func in ${hook_funcs["$1"]}; do - "${func}" + q"${func}" done } @@ -293,13 +327,14 @@ set_consolefont() { for i in /dev/tty[0-9]*; do /usr/bin/setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \ $CONSOLEFONT -C ${i} >/dev/null 2>&1 - done + done if (($? != 0)); then stat_fail elif [[ $CONSOLEMAP ]]; then cat <<"EOF" >>/etc/profile.d/locale.sh -if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi - +if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ] + then printf "\033(K" +fi EOF stat_done fi diff --git a/rc.shutdown b/rc.shutdown index e823ed2..1081970 100755 --- a/rc.shutdown +++ b/rc.shutdown @@ -65,33 +65,17 @@ stat_busy "Unmounting Filesystems" stat_done # Kill non-root encrypted partition mappings -if [[ -f /etc/crypttab ]]; then +if [[ -f /etc/crypttab && $CS ]]; then stat_busy "Deactivating encrypted volumes:" - # Arch cryptsetup packages traditionally contained the binaries - # /usr/sbin/cryptsetup - # /sbin/cryptsetup.static - # By default, initscripts used the /sbin/cryptsetup.static. - # Newer packages will only have /sbin/cryptsetup and no static binary - # This ensures maximal compatibility with the old and new layout - for CS in /sbin/cryptsetup /usr/sbin/cryptsetup \ - /sbin/cryptsetup.static ''; do - [[ -x $CS ]] && break - done - if [[ ! $CS ]]; then - stat_append " Failed, unable to find cryptsetup." - stat_fail - else - while read name src passwd opts; do - [[ ! $name || ${name:0:1} = '#']] && continue - [[ -b /dev/mapper/$name ]] || continue - stat_append "${1}.." - if "$CS" remove "$name" >/dev/null 2>&1; then - stat_append "ok " - else - stat_append "failed " - fi - done </etc/crypttab - fi + do_lock() { + stat_append "${1}.." + if $CS remove "$1" >/dev/null 2>&1; then + stat_append "ok " + else + stat_append "failed " + fi + } + read_crypttab do_lock stat_done fi diff --git a/rc.sysinit b/rc.sysinit index 404e11a..d54b9bb 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -127,104 +127,55 @@ if [[ -f /etc/mdadm.conf ]] && /bin/grep -q ^ARRAY /etc/mdadm.conf; then status "Activating RAID arrays" /sbin/mdadm --assemble --scan fi -if [ "$USELVM" = "yes" -o "$USELVM" = "YES" ]; then - if [ -x /sbin/lvm -a -d /sys/block ]; then - # Kernel 2.6.x, LVM2 groups - /sbin/modprobe -q dm-mod 2>/dev/null - stat_busy "Activating LVM2 groups" - /sbin/lvm vgchange --ignorelockingfailure -a y >/dev/null - if [ $? -ne 0 ]; then - stat_fail - else - stat_done - fi - fi -fi +activate_vgs # Set up non-root encrypted partition mappings -if [ -f /etc/crypttab -a -n "$(/bin/grep -v ^# /etc/crypttab | /bin/grep -v ^$)" ]; then - /sbin/modprobe -q dm-mod 2>/dev/null +if [[ -f /etc/crypttab && $CS ]]; then + /sbin/modprobe -q dm-crypt 2>/dev/null stat_busy "Unlocking encrypted volumes:" - csfailed=0 - # Arch cryptsetup packages traditionally contained the binaries - # /usr/sbin/cryptsetup - # /sbin/cryptsetup.static - # By default, initscripts used the /sbin/cryptsetup.static. - # Newer packages will only have /sbin/cryptsetup and no static binary - # This ensures maximal compatibility with the old and new layout - if [ -x /sbin/cryptsetup ]; then - CS=/sbin/cryptsetup - elif [ -x /usr/sbin/cryptsetup ]; then - CS=/usr/sbin/cryptsetup - else - CS=/sbin/cryptsetup.static - fi - do_crypt() { - if [ $# -ge 3 ]; then - cname="$1" - csrc="$2" - cpass="$3" - shift 3 - copts="$*" - stat_append "${cname}.." - # For some fun reason, the parameter ordering varies for - # LUKS and non-LUKS devices. Joy. - if [ "${cpass}" = "SWAP" ]; then - # This is DANGEROUS! The only possible safety check - # is to not proceed in case we find a LUKS device - # This may cause dataloss if it is not used carefully - if $CS isLuks $csrc 2>/dev/null; then - false - else - $CS -d /dev/urandom $copts create $cname $csrc >/dev/null - if [ $? -eq 0 ]; then - stat_append "creating swapspace.." - /sbin/mkswap -f -L $cname /dev/mapper/$cname >/dev/null - fi - fi - elif [ "${cpass}" = "ASK" ]; then - printf "\nOpening '${cname}' volume:\n" - - if $CS isLuks $csrc 2>/dev/null; then - $CS $copts luksOpen $csrc $cname < /dev/console - else - $CS $copts create $cname $csrc < /dev/console - fi - elif [ "${cpass:0:1}" != "/" ]; then - if $CS isLuks $csrc 2>/dev/null; then - echo "$cpass" | $CS $copts luksOpen $csrc $cname >/dev/null - else - echo "$cpass" | $CS $copts create $cname $csrc >/dev/null - fi - else - if $CS isLuks $csrc 2>/dev/null; then - $CS -d $cpass $copts luksOpen $csrc $cname >/dev/null - else - $CS -d $cpass $copts create $cname $csrc >/dev/null - fi - fi - if [ $? -ne 0 ]; then - csfailed=1 - stat_append "failed " - else - stat_append "ok " - fi - fi - } - while read line; do - eval do_crypt "$line" - done </etc/crypttab - if [ $csfailed -eq 0 ]; then + do_unlock() { + # $1 = requested name + # $2 = source device + # $3 = password + # $4 = options + 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. + if $CS isLuks "$2"; then + open=luksOpen + a="$2" + b="$1" + fi + case $3 in + SWAP) if [[ $_isluks ]]; then + # This is DANGEROUS! The only possible safety check + # is to not proceed in case we find a LUKS device + # This may cause dataloss if it is not used carefully + false + elif $CS -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then + stat_append "creating swapspace.." + /sbin/mkswap -f -L $1 /dev/mapper/$1 >/dev/null + fi;; + ASK) printf "\nOpening '$1' volume:\n" + $CS $4 $open "$a" "$b" < /dev/console;; + /*) $CS -d "$3" $4 $open "$a" "$b" >/dev/null;; + *) echo "$3" | $CS $4 $open "$a" "$b" >/dev/null;; + esac + if (($? != 0)); then + failed=1 + stat_append "failed " + else + stat_append "ok " + fi + return $failed + } + if read_crypttab do_unlock; then stat_done else stat_fail fi # Maybe someone has LVM on an encrypted block device - if [ "$USELVM" = "yes" -o "$USELVM" = "YES" ]; then - if [ -x /sbin/lvm -a -d /sys/block ]; then - /sbin/lvm vgchange --ignorelockingfailure -a y >/dev/null - fi - fi + activate_vgs fi status "Mounting Root Read-only" /bin/mount -n -o remount,ro / -- 1.7.1