aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/dracut/90zfs/zfs-load-key.sh.in
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dracut/90zfs/zfs-load-key.sh.in')
-rwxr-xr-xcontrib/dracut/90zfs/zfs-load-key.sh.in52
1 files changed, 52 insertions, 0 deletions
diff --git a/contrib/dracut/90zfs/zfs-load-key.sh.in b/contrib/dracut/90zfs/zfs-load-key.sh.in
new file mode 100755
index 000000000..d86763fcc
--- /dev/null
+++ b/contrib/dracut/90zfs/zfs-load-key.sh.in
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# 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
+. "$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}" -a "${root##ZFS=}" = "${root}" -a "$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
+if [[ "${root}" = "zfs:AUTO" ]] ; then
+ root=$(zpool list -H -o bootfs | awk '$1 != "-" {print; exit}')
+else
+ root="${root##zfs:}"
+ root="${root##ZFS=}"
+fi
+
+# if pool encryption is active and the zfs command understands '-o encryption'
+if [[ $(zpool list -H -o feature@encryption $(echo "${root}" | awk -F\/ '{print $1}')) == 'active' ]]; then
+ # check if root dataset has encryption enabled
+ if $(zfs list -H -o encryption "${root}" | grep -q -v off); then
+ # figure out where the root dataset has its key, the keylocation should not be none
+ while true; do
+ if [[ $(zfs list -H -o keylocation "${root}") == 'none' ]]; then
+ root=$(echo -n "${root}" | awk 'BEGIN{FS=OFS="/"}{NF--; print}')
+ [[ "${root}" == '' ]] && exit 1
+ else
+ break
+ fi
+ done
+ # decrypt them
+ TRY_COUNT=5
+ while [ $TRY_COUNT != 0 ]; do
+ zfs load-key "$root" <<< $(systemd-ask-password "Encrypted ZFS password for ${root}: ")
+ [[ $? == 0 ]] && break
+ ((TRY_COUNT-=1))
+ done
+ fi
+fi