Hello,

Again I tried to work on this bugreport. I'm absolutely sure that
different bugs are spotted. Most people are hitting the following bug:

the debian-installer was changed to configure devices in fstab and
crypttab in the 'UUID=...' style some time ago. this works for most
systems, with the exception of 'dm-crypt on lvm' setups, where the
encrypted devices are on top of lvm.
the reason is, that the cryptroot initramfs script tries to determine
the volume group from the source device string if the source device is
not available at boot. in the past that was possible for source devices
like '/dev/mapper/vg01-root_crypt'. the lvm volume group is 'vg01'.
for source devices specified as 'UUID=...' this is not possible any
longer.

the only fix i can see, is make the cryptroot initramfs hook determine
the underlying lvm volume group (if any) at mkinitramfs time, and write
the name of the volume group to /conf/conf.d/cryptroot. this information
can be used by the initramfs script at boot time in order to activate
the volume group before trying to unlock the encrypted (logical volume)
device.

i now prepared some ugly patches against cryptroot-hook and
cryptroot-script, that implement what I described above.

the implementation is still very ugly but on my test systems it works.

please give the attached patches a try and see whether they finally fix
the issue for you.
even better would be suggestions on how to improve the implementations,
i.e. provide a more elegant solution.

comments #15, #40, #45, #82, #87, #113, #118 and #123 are about
different issues, which aren't related to this bug.

greetings,
 jonas
--- /usr/share/initramfs-tools/hooks/cryptroot.orig
+++ /usr/share/initramfs-tools/hooks/cryptroot
@@ -230,6 +230,9 @@
 			lvm=*)
 				OPTIONS="$OPTIONS,$opt"
 				;;
+			lvm_vg=*)
+				OPTIONS="$OPTIONS,$opt"
+				;;
 			keyscript=*)
 				opt=${opt#keyscript=}
 				if [ ! -x "/lib/cryptsetup/scripts/$opt" ] && [ ! -x "$opt" ]; then
@@ -338,7 +341,7 @@
 }
 
 add_device() {
-	local node nodes opts lastopts i count
+	local node nodes node_deps node_maj node_min node_depnode node_vg opts lastopts i count
 	nodes="$1"
 	opts=""     # Applied to all nodes
 	lastopts="" # Applied to last node
@@ -374,6 +377,18 @@
 		nodes="$lvmnodes"
 	fi
 
+	# Check for dm-crypt on lvm
+	node_deps=$(dmsetup deps "$nodes" 2>/dev/null | sed 's/[^:]*: *//;s/[ (]//g;s/)/ /g')
+	if [ -n "$node_deps" ]; then
+		node_maj=$(echo ${node_deps%,*} | sed -e "s/^[ \t]*//g")
+		node_min=$(echo ${node_deps#*,} | sed -e "s/[ \t]*$//g")
+		node_depnode=$(dmsetup ls | sed -n "s/\\([^ ]*\\) *($node_maj, $node_min)/\\1/p" | sed -e "s/[ \t]*$//")
+		node_vg=$(lvdisplay "/dev/mapper/$node_depnode" 2>/dev/null | sed -r -e "s|^ +VG Name +([^ ]+) *$|\1|;tx;d;:x")
+		if [ -n "$node_vg" ]; then
+			lastopts="lvm_vg=$node_vg"
+		fi
+	fi
+
 	# Prepare to setup each node
 	count=$(echo "$nodes" | wc -w)
 	i=1
--- /usr/share/initramfs-tools/scripts/local-top/cryptroot.orig
+++ /usr/share/initramfs-tools/scripts/local-top/cryptroot
@@ -100,6 +100,9 @@
 		lvm=*)
 			cryptlvm=${x#lvm=}
 			;;
+		lvm_vg=*)
+			cryptlvm_vg=${x#lvm_vg=}
+			;;
 		keyscript=*)
 			cryptkeyscript=${x#keyscript=}
 			;;
@@ -142,28 +145,32 @@
 activate_vg()
 {
 	local vg
-	vg="${1#/dev/mapper/}"
-
-	# Sanity checks
-	if [ ! -x /sbin/lvm ]; then
-		message "cryptsetup: lvm is not available"
-		return 1
- 	elif [ "$vg" = "$1" ]; then
-		message "cryptsetup: lvm device name ($vg) does not begin with /dev/mapper/"
-		return 1
-	fi
+	if [ -n "$cryptlvm_vg" ]; then
+		vg="$cryptlvm_vg"
+	else
+		vg="${1#/dev/mapper/}"
+
+		# Sanity checks
+		if [ ! -x /sbin/lvm ]; then
+			message "cryptsetup: lvm is not available"
+			return 1
+	 	elif [ "$vg" = "$1" ]; then
+			message "cryptsetup: lvm device name ($vg) does not begin with /dev/mapper/"
+			return 1
+		fi
 
-	# Make sure that the device contains at least one dash
-	if [ "${vg%%-*}" = "$vg" ]; then
-		message "cryptsetup: lvm device name ($vg) does not contain a dash"
-		return 1
-	fi
+		# Make sure that the device contains at least one dash
+		if [ "${vg%%-*}" = "$vg" ]; then
+			message "cryptsetup: lvm device name ($vg) does not contain a dash"
+			return 1
+		fi
 
-	# Split volume group from logical volume.
-	vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
+		# Split volume group from logical volume.
+		vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
 
-	# Reduce padded --'s to -'s
-	vg=$(echo ${vg} | sed -e 's#--#-#g')
+		# Reduce padded --'s to -'s
+		vg=$(echo ${vg} | sed -e 's#--#-#g')
+	fi
 
 	lvm vgchange -ay ${vg}
 	return $?

Attachment: signature.asc
Description: Digital signature

Reply via email to