1#!/bin/sh 2# shellcheck disable=SC2154 3 4# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise 5[ -e /bin/systemctl ] || [ -e /usr/bin/systemctl ] || return 0 6 7# shellcheck source=zfs-lib.sh.in 8. /lib/dracut-zfs-lib.sh 9 10decode_root_args || return 0 11 12# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported 13while ! systemctl is-active --quiet zfs-import.target; do 14 systemctl is-failed --quiet zfs-import-cache.service zfs-import-scan.service && return 1 15 sleep 0.1s 16done 17 18BOOTFS="$root" 19if [ "$BOOTFS" = "zfs:AUTO" ]; then 20 BOOTFS="$(zpool get -Ho value bootfs | grep -m1 -vFx -)" 21fi 22 23[ "$(zpool get -Ho value feature@encryption "${BOOTFS%%/*}")" = 'active' ] || return 0 24 25_load_key_cb() { 26 dataset="$1" 27 28 ENCRYPTIONROOT="$(zfs get -Ho value encryptionroot "${dataset}")" 29 [ "${ENCRYPTIONROOT}" = "-" ] && return 0 30 31 [ "$(zfs get -Ho value keystatus "${ENCRYPTIONROOT}")" = "unavailable" ] || return 0 32 33 KEYLOCATION="$(zfs get -Ho value keylocation "${ENCRYPTIONROOT}")" 34 case "${KEYLOCATION%%://*}" in 35 prompt) 36 for _ in 1 2 3; do 37 systemd-ask-password --timeout=0 --no-tty "Encrypted ZFS password for ${dataset}" | zfs load-key "${ENCRYPTIONROOT}" && break 38 done 39 ;; 40 http*) 41 systemctl start network-online.target 42 zfs load-key "${ENCRYPTIONROOT}" 43 ;; 44 file) 45 KEYFILE="${KEYLOCATION#file://}" 46 [ -r "${KEYFILE}" ] || udevadm settle 47 [ -r "${KEYFILE}" ] || { 48 info "ZFS: Waiting for key ${KEYFILE} for ${ENCRYPTIONROOT}..." 49 for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do 50 sleep 0.5s 51 [ -r "${KEYFILE}" ] && break 52 done 53 } 54 [ -r "${KEYFILE}" ] || warn "ZFS: Key ${KEYFILE} for ${ENCRYPTIONROOT} hasn't appeared. Trying anyway." 55 zfs load-key "${ENCRYPTIONROOT}" 56 ;; 57 *) 58 zfs load-key "${ENCRYPTIONROOT}" 59 ;; 60 esac 61} 62 63_load_key_cb "$BOOTFS" 64for_relevant_root_children "$BOOTFS" _load_key_cb 65