~alpine/aports

Add support for unlocking multi-device root v2 SUPERSEDED

Wolf: 1
 Add support for unlocking multi-device root

 2 files changed, 103 insertions(+), 5 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.alpinelinux.org/~alpine/aports/patches/3068/mbox | git am -3
Learn more about email & git

[PATCH v2] Add support for unlocking multi-device root Export this patch

Add cryptroo[0-9]= family of options to allow unlocking multi-device
root filesystems, which is needed for btrfs raid1.
---
Suppress output of dd.

 initramfs-init.in       | 80 ++++++++++++++++++++++++++++++++++++++---
 mkinitfs-bootparam.7.in | 28 +++++++++++++++
 2 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/initramfs-init.in b/initramfs-init.in
index 4f96b7c..f358b2a 100755
--- a/initramfs-init.in
+++ b/initramfs-init.in
@@ -311,11 +311,15 @@ mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm
#  acpi_osi="!Windows 2006" xen-pciback.hide=(01:00.0)
set -- $(cat /proc/cmdline)

myopts="alpine_dev autodetect autoraid chart cryptroot cryptdm cryptheader cryptoffset
	cryptdiscards cryptkey debug_init dma init init_args keep_apk_new modules ovl_dev
	pkgs quiet root_size root usbdelay ip alpine_repo apkovl alpine_start splash
	blacklist overlaytmpfs rootfstype rootflags nbd resume s390x_net dasd ssh_key
	BOOTIF"
myopts="alpine_dev autodetect autoraid chart cryptroot cryptdm cryptheader
	cryptoffset cryptdiscards cryptkey debug_init dma init init_args
	keep_apk_new modules ovl_dev pkgs quiet root_size root usbdelay ip
	alpine_repo apkovl alpine_start splash blacklist overlaytmpfs rootfstype
	rootflags nbd resume s390x_net dasd ssh_key BOOTIF"
for i in `seq 0 9`; do
	myopts="$myopts cryptroot$i cryptdm$i cryptheader$i cryptoffset$i
		cryptdiscards$i cryptkey$i"
done

for opt; do
	case "$opt" in
@@ -442,6 +446,72 @@ if [ -n "$KOPT_cryptroot" ]; then
	fi
fi

(
# Helper functions to avoid obscuring logic with so many evals
for var in cryptroot cryptdiscards cryptdm cryptoffset cryptheader cryptkey; do
	eval "$var() { eval 'printf -- %s \"\$KOPT_$var'\$1'\"'; }"
done
for i in `seq 0 9`; do
	[ -n "$(cryptroot $i)" ] || continue
	any=true

	ebegin "Opening encrypted device $(cryptroot $i)"

	opts="-c $(cryptroot $i)"

	if [ "$(cryptdiscards $i)" = "yes" ]; then
		opts="$opts -D"
	fi

	if [ -n "$(cryptdm $i)" ]; then
		name="$(cryptdm $i)"
	else
		name=$(
			dd if=/dev/urandom bs=4096 count=1 2>/dev/null \
				| sha1sum | tr -d \ -
		)
		cat >&2 <<-EOF
WARNING: cryptsetup does not work without having a device name set. You should
         provide one using cryptdm$i=. Using temporary name:
             $name.
		EOF
	fi
	opts="$opts -m $name"

	if [ -n "$(cryptheader $i)" ]; then
		opts="$opts -H $(cryptheader $i)"
	fi

	if [ -n "$(cryptoffset $i)" ]; then
		opts="$opts -o $(cryptoffset $i)"
	fi

	if [ "$(cryptkey $i)" = "yes" ]; then
		opts="$opts -k /crypto_keyfile.bin"
	elif [ -n "$(cryptkey $i)" ]; then
		opts="$opts -k $(cryptkey $i)"
	fi

	nlplug-findfs $opts -p /sbin/mdev ${KOPT_debug_init:+-d} \
		${KOPT_usbdelay:+-t $(( $KOPT_usbdelay * 1000 ))} \
		/dev/mapper/"$name"
	eend $?
done

# We need to continue only if there is at least one cryptrootX specified
[ "$any" = "true" ] || exit 0

# Since btrfs needs all devices to be present, scanning cannot be done by the
# nlplug-findfs above. So lets do both lvm and btrfs manually here.
if [ -x /sbin/lvm ]; then
	/sbin/lvm vgchange -aya --noudevsync --sysinit -qq
fi
if [ -x /sbin/btrfs ]; then
	/sbin/btrfs device scan >/dev/null || \
		echo "Failed to scan devices for btrfs filesystem."
fi
)

if [ -n "$KOPT_nbd" ]; then
	# TODO: Might fail because nlplug-findfs hasn't plugged eth0 yet
	configure_ip
diff --git a/mkinitfs-bootparam.7.in b/mkinitfs-bootparam.7.in
index d5a3aad..deca9c0 100644
--- a/mkinitfs-bootparam.7.in
+++ b/mkinitfs-bootparam.7.in
@@ -27,20 +27,39 @@ security implications.
After the block device has been decrypted, make it available as
/dev/mapper/\fINAME\fR.
.TP
\fBcryptdm[0-9]=\fINAME\fR
After the block device has been decrypted, make it available as
/dev/mapper/\fINAME\fR. See "CRYPTO NOTES" for details.
.TP
\fBcryptheader=\fIDEVICE\fR
When the LUKS headers and encrypted data are on different devices, this option
specifies the device with the LUKS headers.
.TP
\fBcryptheader[0-9]=\fIDEVICE\fR
When the LUKS headers and encrypted data are on different devices, this option
specifies the device with the LUKS headers. See "CRYPTO NOTES" for details.
.TP
\fBcryptkey=\fIKEYFILE\fR
Attempt to decrypt an encypted partition using an keyfile.
.TP
\fBcryptkey[0-9]=\fIKEYFILE\fR
Attempt to decrypt an encypted partition using an keyfile. See "CRYPTO NOTES"
for details.
.TP
\fBcryptoffset=\fISECTORS\fR
Indicate that the encrypted data begins the given number of sectors after the
start of the block device.
.TP
\fBcryptoffset[0-9]=\fISECTORS\fR
Indicate that the encrypted data begins the given number of sectors after the
start of the block device. See "CRYPTO NOTES" for details.
.TP
\fBcryptroot=\fIDEVICE\fR
Attempt to decrypt \fIDEVICE\fR.
.TP
\fBcryptroot[0-9]=\fIDEVICE\fR
Attempt to decrypt \fIDEVICE\fR. See "CRYPTO NOTES" for details.
.TP
\fBdasd\fR
Enable DASD devices on S/390x architectures.
.TP
@@ -123,6 +142,15 @@ media.
.TP
\fI@datadir@/initramfs-init\fR
Default script that will be run in the initramfs.
.SH CRYPTO NOTES
There are two ways to specify what encrypted device should be unlocked.
.PP
One is \fBcryptroot=\fR family of options. 99% of the time this is what you want
to use. It works just fine as long as you need to unlock just one device.
.PP
Other is \fBcryptroot[0-9]=\fR family of options. When you have your root on
for example btrfs raid1, you need to unlock multiple devices. Up to 10 devices
can be specified.
.SH AUTHOR
.PP
Written by Natanael Copa <ncopa@alpinelinux.org>, Timo Teräs <timo.teras@iki.fi> and others.
-- 
2.23.0