From 5a8e472335e58f3e2310b8d8161384af95f4c2a6 Mon Sep 17 00:00:00 2001 From: Victor Lowther Date: Wed, 9 Jun 2010 10:52:15 -0500 Subject: Rewrite /etc/crypttab processing. 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 | 34 ++++++++++++++++ rc.shutdown | 38 +++++------------- rc.sysinit | 131 +++++++++++++++++++----------------------------------------- 3 files changed, 86 insertions(+), 117 deletions(-) diff --git a/functions b/functions index 84fed85..b9ba718 100644 --- a/functions +++ b/functions @@ -233,6 +233,40 @@ kill_everything() { run_hook "$1_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[0]}" "${nspo[1]}" "${nspo[2]}" "${nspo[@]:3}" || failed=1 + done < /etc/crypttab + return $failed +} + ############################### # Custom hooks in initscripts # ############################### diff --git a/rc.shutdown b/rc.shutdown index 07061e8..84003dd 100755 --- a/rc.shutdown +++ b/rc.shutdown @@ -65,34 +65,18 @@ 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 /dev/null 2>&1; then + stat_append "ok " + else + stat_append "failed " + fi + } + read_crypttab do_lock + stat_done fi if [[ $USELVM =~ yes|YES && -x /sbin/lvm && -d /sys/block ]]; then diff --git a/rc.sysinit b/rc.sysinit index 0732fdf..3caee66 100755 --- a/rc.sysinit +++ b/rc.sysinit @@ -121,104 +121,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 /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 / -- cgit v1.2.3