mirror_zfs/contrib/dracut/90zfs/zfs-load-key.sh.in
sam-lunt 5b8f560713 In initramfs, do not prompt if keylocation is "file://"
If the encryption key is stored in a file, the initramfs should not
prompt for the password. For example, this could be the case if the boot
partition is stored on removable media that is only present at boot time

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Garrett Fields <ghfields@gmail.com>
Reviewed-by: Richard Laager <rlaager@wiktel.com>
Reviewed-by: Kjeld Schouten <kjeld@schouten-lebbing.nl>
Signed-off-by: Sam Lunt <samuel.j.lunt@gmail.com>
Closes #9764
2020-01-22 13:49:06 -08:00

59 lines
2.6 KiB
Bash
Executable File

#!/bin/sh
# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise
[ -e /bin/systemctl ] || return 0
# This script only gets executed on systemd systems, see mount-zfs.sh for non-systemd systems
# import the libs now that we know the pool imported
[ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh
[ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh
# shellcheck source=./lib-zfs.sh.in
. "$dracutlib"
# load the kernel command line vars
[ -z "$root" ] && root="$(getarg root=)"
# If root is not ZFS= or zfs: or rootfstype is not zfs then we are not supposed to handle it.
[ "${root##zfs:}" = "${root}" ] && [ "${root##ZFS=}" = "${root}" ] && [ "$rootfstype" != "zfs" ] && exit 0
# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported
while true; do
zpool list -H | grep -q -v '^$' && break
[ "$(systemctl is-failed zfs-import-cache.service)" = 'failed' ] && exit 1
[ "$(systemctl is-failed zfs-import-scan.service)" = 'failed' ] && exit 1
sleep 0.1s
done
# run this after import as zfs-import-cache/scan service is confirmed good
# we do not overwrite the ${root} variable, but create a new one, BOOTFS, to hold the dataset
if [ "${root}" = "zfs:AUTO" ] ; then
BOOTFS="$(zpool list -H -o bootfs | awk '$1 != "-" {print; exit}')"
else
BOOTFS="${root##zfs:}"
BOOTFS="${BOOTFS##ZFS=}"
fi
# if pool encryption is active and the zfs command understands '-o encryption'
if [ "$(zpool list -H -o feature@encryption $(echo "${BOOTFS}" | awk -F\/ '{print $1}'))" = 'active' ]; then
# if the root dataset has encryption enabled
ENCRYPTIONROOT=$(zfs get -H -o value encryptionroot "${BOOTFS}")
# where the key is stored (in a file or loaded via prompt)
KEYLOCATION=$(${ZFS} get -H -o value keylocation "${ENCRYPTIONROOT}")
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")"
# continue only if the key needs to be loaded
[ "$KEYSTATUS" = "unavailable" ] || exit 0
# if key is stored in a file, do not prompt
if ! [ "${KEYLOCATION}" = "prompt" ]; then
zfs load-key "${ENCRYPTIONROOT}"
else
# decrypt them
TRY_COUNT=5
while [ $TRY_COUNT -gt 0 ]; do
systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break
TRY_COUNT=$((TRY_COUNT - 1))
done
fi
fi
fi