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