[arch-general] [PATCH 32/48] Rewrite /etc/crypttab processing.

Victor Lowther victor.lowther at gmail.com
Wed Jun 30 17:47:45 EDT 2010


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



More information about the arch-general mailing list