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# This script only gets executed on systemd systems, see mount-zfs.sh for non-systemd systems 8 9# import the libs now that we know the pool imported 10[ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh 11[ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh 12# shellcheck source=./lib-zfs.sh.in 13. "$dracutlib" 14 15# load the kernel command line vars 16[ -z "$root" ] && root="$(getarg root=)" 17# If root is not ZFS= or zfs: or rootfstype is not zfs then we are not supposed to handle it. 18[ "${root##zfs:}" = "${root}" ] && [ "${root##ZFS=}" = "${root}" ] && [ "$rootfstype" != "zfs" ] && exit 0 19 20# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported 21while [ "$(zpool list -H)" = "" ]; do 22 systemctl is-failed --quiet zfs-import-cache.service zfs-import-scan.service && exit 1 23 sleep 0.1s 24done 25 26# run this after import as zfs-import-cache/scan service is confirmed good 27# we do not overwrite the ${root} variable, but create a new one, BOOTFS, to hold the dataset 28if [ "${root}" = "zfs:AUTO" ] ; then 29 BOOTFS="$(zpool list -H -o bootfs | awk '$1 != "-" {print; exit}')" 30else 31 BOOTFS="${root##zfs:}" 32 BOOTFS="${BOOTFS##ZFS=}" 33fi 34 35# if pool encryption is active and the zfs command understands '-o encryption' 36if [ "$(zpool list -H -o feature@encryption "${BOOTFS%%/*}")" = 'active' ]; then 37 # if the root dataset has encryption enabled 38 ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${BOOTFS}")" 39 if ! [ "${ENCRYPTIONROOT}" = "-" ]; then 40 KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")" 41 # continue only if the key needs to be loaded 42 [ "$KEYSTATUS" = "unavailable" ] || exit 0 43 44 KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")" 45 case "${KEYLOCATION%%://*}" in 46 prompt) 47 for _ in 1 2 3; do 48 systemd-ask-password --no-tty "Encrypted ZFS password for ${BOOTFS}" | zfs load-key "${ENCRYPTIONROOT}" && break 49 done 50 ;; 51 http*) 52 systemctl start network-online.target 53 zfs load-key "${ENCRYPTIONROOT}" 54 ;; 55 file) 56 KEYFILE="${KEYLOCATION#file://}" 57 [ -r "${KEYFILE}" ] || udevadm settle 58 [ -r "${KEYFILE}" ] || { 59 info "Waiting for key ${KEYFILE} for ${ENCRYPTIONROOT}..." 60 for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do 61 sleep 0.5s 62 [ -r "${KEYFILE}" ] && break 63 done 64 } 65 [ -r "${KEYFILE}" ] || warn "Key ${KEYFILE} for ${ENCRYPTIONROOT} hasn't appeared. Trying anyway." 66 zfs load-key "${ENCRYPTIONROOT}" 67 ;; 68 *) 69 zfs load-key "${ENCRYPTIONROOT}" 70 ;; 71 esac 72 fi 73fi 74