diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts index 506f8c6c..aecbaec1 100644 --- a/defaults/initrd.scripts +++ b/defaults/initrd.scripts @@ -1791,6 +1791,19 @@ start_volumes() { if [ $? -ne 0 ] then bad_msg "Import of ${ZFS_POOL} failed!" + elif [ "${ZFS_LOADKEY_FOR_ALL}" = '1' ] + then + good_msg "Importing other ZFS pools ..." + + local zfs_cmd="run /sbin/zpool import -N -a ${ZPOOL_CACHE} ${ZPOOL_FORCE} 2>&1" + is_log_enabled && zfs_cmd="${zfs_cmd} | tee -a '${GK_INIT_LOG}'" + is_quiet && zfs_cmd="${zfs_cmd} 1>/dev/null" + + eval "${zfs_cmd}" + if [ $? -ne 0 ] + then + bad_msg "Importing ZFS pools failed!" + fi fi fi fi diff --git a/defaults/linuxrc b/defaults/linuxrc index 34b2d878..fe1f760c 100644 --- a/defaults/linuxrc +++ b/defaults/linuxrc @@ -131,6 +131,18 @@ do fi ;; esac + + case "${x#*=}" in + *loadkeyall*) + ZFS_LOADKEY_FOR_ALL=1 + ;; + esac + + case "${x#*=}" in + *unifiedkey*) + ZFS_LOADKEY_UNIFIED=1 + ;; + esac ;; quiet|quiet_genkernel) QUIET=1 @@ -923,7 +935,28 @@ do if [ "${ZFS_ENCRYPTIONROOT}" != '-' ] && [ "${ZFS_KEYSTATUS}" = 'unavailable' ] then good_msg "Detected ZFS encryption, asking for key" - run zfs load-key "${ZFS_ENCRYPTIONROOT}" + if [ "${ZFS_LOADKEY_FOR_ALL}" = '1' ] + then + if [ "${ZFS_LOADKEY_UNIFIED}" = '1' ] + then + echo -n "Enter unified passphrase for ZFS dataset ${ZFS_ENCRYPTIONROOT}: " + stty -echo + ZFS_PASSWORD=$(head -n 1 | tr -d '\n') + stty echo + echo + + if [ -n "${ZFS_PASSWORD}" ] + then + yes "${ZFS_PASSWORD}" | run zfs load-key -a + fi + ZFS_PASSWORD="00000000000000000000000000000000" + unset ZFS_PASSWORD + else + run zfs load-key -a + fi + else + run zfs load-key "${ZFS_ENCRYPTIONROOT}" + fi # Get new key status to check if load-key was successful # or dataset has been opened by someone else in the meantime (through SSH for instance) diff --git a/defaults/login-remote.sh b/defaults/login-remote.sh index 4664d7bd..10e070ed 100644 --- a/defaults/login-remote.sh +++ b/defaults/login-remote.sh @@ -104,6 +104,7 @@ else if [ -e "${ZFS_ENC_ENV_FILE}" ] && [ ! -f "${ZFS_ENC_OPENED_LOCKFILE}" ] then good_msg "${NORMAL}To remote unlock ZFS root device, run '${BOLD}unlock-zfs${NORMAL}'." + good_msg "${NORMAL}To unlock all ZFS devices, run '${bold}unlock-zfs -a${normal}', or '${bold}unlock-zfs -a -u${normal}' for unified key." fi echo diff --git a/defaults/unlock-zfs.sh b/defaults/unlock-zfs.sh index c22a2146..add5f00e 100644 --- a/defaults/unlock-zfs.sh +++ b/defaults/unlock-zfs.sh @@ -1,5 +1,31 @@ #!/bin/sh +print_usage() { + echo "Usage: $0 [-a] [-u]" >&2 +} + +case "${1}" in + -a) + ZFS_LOADKEY_FOR_ALL=1 + ;; + -u) + ZFS_LOADKEY_UNIFIED=1 + ;; + -h) + print_usage + exit 1 + ;; +esac + +case "${2}" in + -a) + ZFS_LOADKEY_FOR_ALL=1 + ;; + -u) + ZFS_LOADKEY_UNIFIED=1 + ;; +esac + . /etc/initrd.defaults . /etc/initrd.scripts @@ -62,7 +88,24 @@ main() { break fi - zfs load-key "${ZFS_ENCRYPTIONROOT}" + if [ "${ZFS_LOADKEY_FOR_ALL}" = '1' ] + then + if [ "${ZFS_LOADKEY_UNIFIED}" = '1' ] + then + read -s -p "Enter unified passphrase for ZFS dataset ${ZFS_ENCRYPTIONROOT}: " ZFS_PASSWORD + + if [ -n "${ZFS_PASSWORD}" ] + then + yes "${ZFS_PASSWORD}" | run zfs load-key -a + fi + ZFS_PASSWORD="00000000000000000000000000000000" + unset ZFS_PASSWORD + else + zfs load-key -a + fi + else + zfs load-key "${ZFS_ENCRYPTIONROOT}" + fi ZFS_KEYSTATUS="$(get_zfs_property "${REAL_ROOT}" keystatus)" if [ "${ZFS_KEYSTATUS}" = 'available' ] @@ -83,6 +126,7 @@ main() { then # Kill any running load-key prompt. run pkill -f "load-key" >/dev/null 2>&1 + run pkill -xf "head -n 1" >/dev/null 2>&1 fi } diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt index 571ab065..c335615e 100644 --- a/doc/genkernel.8.txt +++ b/doc/genkernel.8.txt @@ -882,9 +882,16 @@ when not set. This will allow remote user to provide answer through *domdadm*:: Scan for RAID arrays on bootup. -*dozfs*[=cache,force]:: - Scan for bootable ZFS pools on bootup. Optionally use cachefile or force import if - necessary or perform both actions. +*dozfs*[=cache,force,loadkeyall,unifiedkey]:: + Scan for bootable ZFS pools on bootup. Optionally use cachefile or force + import if necessary or perform both actions. + Optionally ask to unlock all pools with "loadkeyall", equivalent to running + "zfs load-key -a". + Optionally try to use the same key to unlock all possible pools with + "unifiedkey". Must be used with "loadkeyall". Only passphrase is supported. + If the passphrase fails to unlock some pools, it will continue the boot + process unless it is the root pool. + *domultipath*:: Activate Multipath on bootup.