1#!/bin/sh 2# shellcheck disable=SC2034,SC2154 3 4. /lib/dracut-zfs-lib.sh 5 6decode_root_args || return 0 7 8GENERATOR_FILE=/run/systemd/generator/sysroot.mount 9GENERATOR_EXTENSION=/run/systemd/generator/sysroot.mount.d/zfs-enhancement.conf 10 11if [ -e "$GENERATOR_FILE" ] && [ -e "$GENERATOR_EXTENSION" ]; then 12 # We're under systemd and dracut-zfs-generator ran to completion. 13 info "ZFS: Delegating root mount to sysroot.mount at al." 14 15 # We now prevent Dracut from running this thing again. 16 rm -f "$hookdir"/mount/*zfs* 17 return 18fi 19 20info "ZFS: No sysroot.mount exists or zfs-generator did not extend it." 21info "ZFS: Mounting root with the traditional mount-zfs.sh instead." 22 23# ask_for_password tries prompt cmd 24# 25# Wraps around plymouth ask-for-password and adds fallback to tty password ask 26# if plymouth is not present. 27ask_for_password() { 28 tries="$1" 29 prompt="$2" 30 cmd="$3" 31 32 { 33 flock -s 9 34 35 # Prompt for password with plymouth, if installed and running. 36 if plymouth --ping 2>/dev/null; then 37 plymouth ask-for-password \ 38 --prompt "$prompt" --number-of-tries="$tries" | \ 39 eval "$cmd" 40 ret=$? 41 else 42 i=1 43 while [ "$i" -le "$tries" ]; do 44 printf "%s [%i/%i]:" "$prompt" "$i" "$tries" >&2 45 eval "$cmd" && ret=0 && break 46 ret=$? 47 i=$((i+1)) 48 printf '\n' >&2 49 done 50 unset i 51 fi 52 } 9>/.console_lock 53 54 [ "$ret" -ne 0 ] && echo "Wrong password" >&2 55 return "$ret" 56} 57 58 59# Delay until all required block devices are present. 60modprobe zfs 2>/dev/null 61udevadm settle 62 63ZFS_DATASET= 64ZFS_POOL= 65 66if [ "${root}" = "zfs:AUTO" ] ; then 67 if ! ZFS_DATASET="$(zpool get -Ho value bootfs | grep -m1 -vFx -)"; then 68 # shellcheck disable=SC2086 69 zpool import -N -a ${ZPOOL_IMPORT_OPTS} 70 if ! ZFS_DATASET="$(zpool get -Ho value bootfs | grep -m1 -vFx -)"; then 71 warn "ZFS: No bootfs attribute found in importable pools." 72 zpool export -aF 73 74 rootok=0 75 return 1 76 fi 77 fi 78 info "ZFS: Using ${ZFS_DATASET} as root." 79fi 80 81ZFS_DATASET="${ZFS_DATASET:-${root}}" 82ZFS_POOL="${ZFS_DATASET%%/*}" 83 84 85if ! zpool get -Ho value name "${ZFS_POOL}" > /dev/null 2>&1; then 86 info "ZFS: Importing pool ${ZFS_POOL}..." 87 # shellcheck disable=SC2086 88 if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${ZFS_POOL}"; then 89 warn "ZFS: Unable to import pool ${ZFS_POOL}" 90 rootok=0 91 return 1 92 fi 93fi 94 95# Load keys if we can or if we need to 96# TODO: for_relevant_root_children like in zfs-load-key.sh.in 97if [ "$(zpool get -Ho value feature@encryption "${ZFS_POOL}")" = 'active' ]; then 98 # if the root dataset has encryption enabled 99 ENCRYPTIONROOT="$(zfs get -Ho value encryptionroot "${ZFS_DATASET}")" 100 if ! [ "${ENCRYPTIONROOT}" = "-" ]; then 101 KEYSTATUS="$(zfs get -Ho value keystatus "${ENCRYPTIONROOT}")" 102 # if the key needs to be loaded 103 if [ "$KEYSTATUS" = "unavailable" ]; then 104 # decrypt them 105 ask_for_password \ 106 5 \ 107 "Encrypted ZFS password for ${ENCRYPTIONROOT}: " \ 108 "zfs load-key '${ENCRYPTIONROOT}'" 109 fi 110 fi 111fi 112 113# Let us tell the initrd to run on shutdown. 114# We have a shutdown hook to run 115# because we imported the pool. 116info "ZFS: Mounting dataset ${ZFS_DATASET}..." 117if ! mount_dataset "${ZFS_DATASET}"; then 118 rootok=0 119 return 1 120fi 121