]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/dracut/90zfs/zfs-load-key.sh.in
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / contrib / dracut / 90zfs / zfs-load-key.sh.in
1 #!/bin/bash
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
20 while true; do
21     zpool list -H | grep -q -v '^$' && break
22     [ "$(systemctl is-failed zfs-import-cache.service)" = 'failed' ] && exit 1
23     [ "$(systemctl is-failed zfs-import-scan.service)" = 'failed' ] && exit 1
24     sleep 0.1s
25 done
26
27 # run this after import as zfs-import-cache/scan service is confirmed good
28 # we do not overwrite the ${root} variable, but create a new one, BOOTFS, to hold the dataset
29 if [ "${root}" = "zfs:AUTO" ] ; then
30     BOOTFS="$(zpool list -H -o bootfs | awk '$1 != "-" {print; exit}')"
31 else
32     BOOTFS="${root##zfs:}"
33     BOOTFS="${BOOTFS##ZFS=}"
34 fi
35
36 # if pool encryption is active and the zfs command understands '-o encryption'
37 if [ "$(zpool list -H -o feature@encryption $(echo "${BOOTFS}" | awk -F\/ '{print $1}'))" = 'active' ]; then
38     # if the root dataset has encryption enabled
39     ENCRYPTIONROOT=$(zfs get -H -o value encryptionroot "${BOOTFS}")
40     # where the key is stored (in a file or loaded via prompt)
41     KEYLOCATION=$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")
42     if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
43         KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")"
44         # continue only if the key needs to be loaded
45         [ "$KEYSTATUS" = "unavailable" ] || exit 0
46         # if key is stored in a file, do not prompt
47         if ! [ "${KEYLOCATION}" = "prompt" ]; then
48             zfs load-key "${ENCRYPTIONROOT}"
49         else
50             # decrypt them
51             TRY_COUNT=5
52             while [ $TRY_COUNT -gt 0 ]; do
53                 systemd-ask-password "Encrypted ZFS password for ${BOOTFS}" --no-tty | zfs load-key "${ENCRYPTIONROOT}" && break
54                 TRY_COUNT=$((TRY_COUNT - 1))
55             done
56         fi
57     fi
58 fi