diff --git a/etc/systemd/system-generators/zfs-mount-generator.in b/etc/systemd/system-generators/zfs-mount-generator.in index 2eba74716..850396fb6 100755 --- a/etc/systemd/system-generators/zfs-mount-generator.in +++ b/etc/systemd/system-generators/zfs-mount-generator.in @@ -74,6 +74,62 @@ process_line() { p_encroot="${11}" p_keyloc="${12}" + # Minimal pre-requisites to mount a ZFS dataset + wants="zfs-import.target" + + # Handle encryption + if [ -n "${p_encroot}" ] && + [ "${p_encroot}" != "-" ] ; then + keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service" + if [ "${p_encroot}" = "${dataset}" ] ; then + pathdep="" + if [ "${p_keyloc%%://*}" = "file" ] ; then + pathdep="RequiresMountsFor='${p_keyloc#file://}'" + keyloadcmd="@sbindir@/zfs load-key '${dataset}'" + elif [ "${p_keyloc}" = "prompt" ] ; then + keyloadcmd="/bin/sh -c 'set -eu;"\ +"keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";"\ +"[ \"\$\$keystatus\" = \"unavailable\" ] || exit 0;"\ +"count=0;"\ +"while [ \$\$count -lt 3 ];do"\ +" systemd-ask-password --id=\"zfs:${dataset}\""\ +" \"Enter passphrase for ${dataset}:\"|"\ +" @sbindir@/zfs load-key \"${dataset}\" && exit 0;"\ +" count=\$\$((count + 1));"\ +"done;"\ +"exit 1'" + else + printf 'zfs-mount-generator: (%s) invalid keylocation\n' \ + "${dataset}" >/dev/kmsg + fi + + # Generate the key-load .service unit + cat > "${dest_norm}/${keyloadunit}" << EOF +# Automatically generated by zfs-mount-generator + +[Unit] +Description=Load ZFS key for ${dataset} +SourcePath=${cachefile} +Documentation=man:zfs-mount-generator(8) +DefaultDependencies=no +Wants=${wants} +After=${wants} +${pathdep} + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=${keyloadcmd} +ExecStop=@sbindir@/zfs unload-key '${dataset}' +EOF + fi + # Update the dependencies for the mount file to require the + # key-loading unit. + wants="${wants} ${keyloadunit}" + fi + + # Prepare the .mount unit + # Check for canmount=off . if [ "${p_canmount}" = "off" ] ; then return @@ -170,56 +226,6 @@ process_line() { "${dataset}" >/dev/kmsg fi - # Minimal pre-requisites to mount a ZFS dataset - wants="zfs-import.target" - if [ -n "${p_encroot}" ] && - [ "${p_encroot}" != "-" ] ; then - keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service" - if [ "${p_encroot}" = "${dataset}" ] ; then - pathdep="" - if [ "${p_keyloc%%://*}" = "file" ] ; then - pathdep="RequiresMountsFor='${p_keyloc#file://}'" - keyloadcmd="@sbindir@/zfs load-key '${dataset}'" - elif [ "${p_keyloc}" = "prompt" ] ; then - keyloadcmd="/bin/sh -c 'set -eu;"\ -"keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";"\ -"[ \"\$\$keystatus\" = \"unavailable\" ] || exit 0;"\ -"count=0;"\ -"while [ \$\$count -lt 3 ];do"\ -" systemd-ask-password --id=\"zfs:${dataset}\""\ -" \"Enter passphrase for ${dataset}:\"|"\ -" @sbindir@/zfs load-key \"${dataset}\" && exit 0;"\ -" count=\$\$((count + 1));"\ -"done;"\ -"exit 1'" - else - printf 'zfs-mount-generator: (%s) invalid keylocation\n' \ - "${dataset}" >/dev/kmsg - fi - cat > "${dest_norm}/${keyloadunit}" << EOF -# Automatically generated by zfs-mount-generator - -[Unit] -Description=Load ZFS key for ${dataset} -SourcePath=${cachefile} -Documentation=man:zfs-mount-generator(8) -DefaultDependencies=no -Wants=${wants} -After=${wants} -${pathdep} - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=${keyloadcmd} -ExecStop=@sbindir@/zfs unload-key '${dataset}' -EOF - fi - # Update the dependencies for the mount file to require the - # key-loading unit. - wants="${wants} ${keyloadunit}" - fi - # If the mountpoint has already been created, give it precedence. if [ -e "${dest_norm}/${mountfile}" ] ; then printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \ @@ -227,6 +233,7 @@ EOF return fi + # Create the .mount unit file. # By ordering before zfs-mount.service, we avoid race conditions. cat > "${dest_norm}/${mountfile}" << EOF # Automatically generated by zfs-mount-generator