1#!/bin/sh 2 3# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise 4[ -e /bin/systemctl ] || return 0 5 6# This script only gets executed on systemd systems, see mount-zfs.sh for non-systemd systems 7 8# import the libs now that we know the pool imported 9[ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh 10[ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh 11# shellcheck source=./lib-zfs.sh.in 12. "$dracutlib" 13 14# load the kernel command line vars 15[ -z "$root" ] && root="$(getarg root=)" 16# If root is not ZFS= or zfs: or rootfstype is not zfs then we are not supposed to handle it. 17[ "${root##zfs:}" = "${root}" ] && [ "${root##ZFS=}" = "${root}" ] && [ "$rootfstype" != "zfs" ] && exit 0 18 19# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported 20while [ "$(zpool list -H)" = "" ]; do 21 systemctl is-failed --quiet zfs-import-cache.service zfs-import-scan.service && exit 1 22 sleep 0.1s 23done 24 25# run this after import as zfs-import-cache/scan service is confirmed good 26# we do not overwrite the ${root} variable, but create a new one, BOOTFS, to hold the dataset 27if [ "${root}" = "zfs:AUTO" ] ; then 28 BOOTFS="$(zpool list -H -o bootfs | awk '$1 != "-" {print; exit}')" 29else 30 BOOTFS="${root##zfs:}" 31 BOOTFS="${BOOTFS##ZFS=}" 32fi 33 34# if pool encryption is active and the zfs command understands '-o encryption' 35if [ "$(zpool list -H -o feature@encryption "$(echo "${BOOTFS}" | awk -F/ '{print $1}')")" = 'active' ]; then 36 # if the root dataset has encryption enabled 37 ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${BOOTFS}")" 38 # where the key is stored (in a file or loaded via prompt) 39 KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")" 40 if ! [ "${ENCRYPTIONROOT}" = "-" ]; then 41 KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")" 42 # continue only if the key needs to be loaded 43 [ "$KEYSTATUS" = "unavailable" ] || exit 0 44 # if key is stored in a file, do not prompt 45 if ! [ "${KEYLOCATION}" = "prompt" ]; then 46 zfs load-key "${ENCRYPTIONROOT}" 47 else 48 # decrypt them 49 TRY_COUNT=5 50 while [ $TRY_COUNT -gt 0 ]; do 51 systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break 52 TRY_COUNT=$((TRY_COUNT - 1)) 53 done 54 fi 55 fi 56fi 57