diff --git a/decrypt-root-with-usb/ubuntu-20.04/cryptroot.patch b/decrypt-root-with-usb/ubuntu-20.04/cryptroot.patch index ba76ce1..042132f 100644 --- a/decrypt-root-with-usb/ubuntu-20.04/cryptroot.patch +++ b/decrypt-root-with-usb/ubuntu-20.04/cryptroot.patch @@ -1,35 +1,28 @@ ---- /usr/share/initramfs-tools/scripts/local-top/cryptroot.orig 2020-05-03 01:25:43.388812582 +0200 -+++ /usr/share/initramfs-tools/scripts/local-top/cryptroot 2020-05-03 01:25:43.392812547 +0200 -@@ -123,6 +123,23 @@ - fi - fi - -+ if [ -z "${CRYPTTAB_OPTION_keyscript+x}" ]; then -+ # Wait for USB to settle -+ /bin/sleep 3 -+ -+ # Test all devices -+ mkdir /mnt -+ echo -n "Searching for cryptkey.txt on available disks... " -+ local partition -+ for partition in `cat /proc/partitions |awk '{print $4}'|tail -n +3`; do -+ if mount /dev/$partition /mnt 2>/dev/null; then -+ cat /mnt/cryptkey.txt >> /tmp/cryptkeys.txt 2>/dev/null -+ umount /dev/$partition -+ fi -+ done -+ echo "done." -+ fi -+ - get_crypt_type # set CRYPTTAB_TYPE to the type of crypt device - local count=0 maxtries="${CRYPTTAB_OPTION_tries:-3}" fstype vg rv - while [ $maxtries -le 0 ] || [ $count -lt $maxtries ]; do -@@ -130,8 +147,29 @@ +--- /usr/share/initramfs-tools/scripts/local-top/cryptroot 2020-09-16 22:40:05.000000000 +0200 ++++ cryptroot 2020-11-23 22:31:48.797985438 +0100 +@@ -162,8 +162,46 @@ # unlock via keyfile unlock_mapping "$CRYPTTAB_KEY" else - # unlock interactively or via keyscript - run_keyscript "$CRYPTTAB_KEY" "$count" | unlock_mapping ++ if [ -z "${CRYPTTAB_OPTION_keyscript+x}" ]; then ++ # Wait for USB to settle ++ /bin/sleep 3 ++ ++ # Test all devices ++ mkdir /mnt ++ echo -n "Searching for cryptkey.txt on available disks... " ++ local partition ++ for partition in `cat /proc/partitions |awk '{print $4}'|tail -n +3`; do ++ if mount /dev/$partition /mnt 2>/dev/null; then ++ cat /mnt/cryptkey.txt >> /tmp/cryptkeys.txt 2>/dev/null ++ umount /dev/$partition ++ fi ++ done ++ echo "done." ++ fi ++ + if [ -s /tmp/cryptkeys.txt ]; then + local keyfound + keyfound=0 diff --git a/decrypt-root-with-usb/ubuntu-20.04/usr/share/initramfs-tools/scripts/local-top/cryptroot b/decrypt-root-with-usb/ubuntu-20.04/usr/share/initramfs-tools/scripts/local-top/cryptroot index 288aa1a..18216ef 100644 --- a/decrypt-root-with-usb/ubuntu-20.04/usr/share/initramfs-tools/scripts/local-top/cryptroot +++ b/decrypt-root-with-usb/ubuntu-20.04/usr/share/initramfs-tools/scripts/local-top/cryptroot @@ -31,8 +31,8 @@ esac # wait_for_source() -# Wait for encrypted $CRYPTTAB_SOURCE for up to 180s. Set -# $CRYPTTAB_SOURCE to its normalized device name when it shows up; +# Wait for encrypted $CRYPTTAB_SOURCE . Set $CRYPTTAB_SOURCE +# to its normalized device name when it shows up; # return 1 if timeout. wait_for_source() { wait_for_udev 10 @@ -42,17 +42,27 @@ wait_for_source() { return 0 fi - # The lines below has been taken from - # /usr/share/initramfs-tools/scripts/local's local_device_setup(), - # as suggested per https://launchpad.net/bugs/164044 - # If the source device hasn't shown up yet, give it a little while # to allow for asynchronous device discovery (e.g. USB). + # + # We also need to take into account RAID or other devices that may + # only be available on local-block stage. So, wait 5 seconds upfront, + # in local-top; if that fails, end execution relying on local-block + # invocations. Allow $ROOTDELAY/3 invocations with 1s sleep times (with + # a minimum of 30 invocations), and if after that we still fail, then it's + # really time to give-up. Variable $initrd_cnt tracks the re-invocations. + # + # Part of the lines below has been taken from initramfs-tools + # scripts/local's local_device_setup(), as suggested per + # https://launchpad.net/bugs/164044 . + + local slumber=1 + if [ ! -f "${CRYPTR_LOCAL_BLOCK}" ]; then # we are running on local-top + slumber=5 + fi cryptsetup_message "Waiting for encrypted source device $CRYPTTAB_SOURCE..." - # Default delay is 180s, cf. initramfs-tools(8) - local slumber="${ROOTDELAY:-180}" while [ $slumber -gt 0 ]; do sleep 1 @@ -75,7 +85,23 @@ wait_for_source() { # Set up a crypttab(5) mapping defined by $CRYPTTAB_NAME, # $CRYPTTAB_SOURCE, $CRYPTTAB_KEY, $CRYPTTAB_OPTIONS. setup_mapping() { - local dev + local dev initrd_cnt + + # We control here the number of re-invocations of this script from + # local-block - the heuristic is $ROOTDELAY/3, with a minimum of 30. + # This number is somewhat dictated by mdadm, we want to run more times + # than that script, to allow decrypting volumes on top of arrays. + + if [ -f "${CRYPTR_CNT_FILE}" ]; then + initrd_cnt=$(cat ${CRYPTR_CNT_FILE}) + else + initrd_cnt=${ROOTDELAY:-90} + initrd_cnt=$((initrd_cnt/3)) + if [ "${initrd_cnt}" -lt 30 ]; then + initrd_cnt=30 + fi + echo ${initrd_cnt} > "${CRYPTR_CNT_FILE}" + fi # The same target can be specified multiple times # e.g. root and resume lvs-on-lvm-on-crypto @@ -86,17 +112,23 @@ setup_mapping() { crypttab_parse_options --export --missing-path=fail || return 1 if ! wait_for_source; then - # we've given up - if [ -n "$panic" ]; then - panic "ALERT! encrypted source device $CRYPTTAB_SOURCE does not exist, can't unlock $CRYPTTAB_NAME." - else - # let the user fix matters if they can - echo " ALERT! encrypted source device $CRYPTTAB_SOURCE does not exist, can't unlock $CRYPTTAB_NAME." - echo " Check cryptopts=source= bootarg: cat /proc/cmdline" - echo " or missing modules, devices: cat /proc/modules; ls /dev" - panic "Dropping to a shell." - fi - return 1 # can't continue because environment is lost + if [ ${initrd_cnt} -le 0 ]; then + # we've given up + if [ -n "$panic" ]; then + panic "ALERT! encrypted source device $CRYPTTAB_SOURCE does not exist, can't unlock $CRYPTTAB_NAME." + else + # let the user fix matters if they can + echo " ALERT! encrypted source device $CRYPTTAB_SOURCE does not exist, can't unlock $CRYPTTAB_NAME." + echo " Check cryptopts=source= bootarg: cat /proc/cmdline" + echo " or missing modules, devices: cat /proc/modules; ls /dev" + panic "Dropping to a shell." + fi + return 1 # can't continue because environment is lost + else + initrd_cnt=$((initrd_cnt - 1)) + echo ${initrd_cnt} > "${CRYPTR_CNT_FILE}" + return 0 # allow some attempts on local-block stage + fi fi # our `cryptroot-unlock` script searches for cryptsetup processes @@ -208,6 +240,10 @@ setup_mapping() { done cryptsetup_message "ERROR: $CRYPTTAB_NAME: maximum number of tries exceeded" + + if [ -f "${CRYPTR_CNT_FILE}" ]; then + echo 0 > "${CRYPTR_CNT_FILE}" + fi exit 1 }