Skip to content

Commit

Permalink
contrib: dracut: inline single-use import_pool, move single-use ask_f…
Browse files Browse the repository at this point in the history
…or_password

Also don't set ROOTFS_MOUNTED; the final mention was removed in dracut
011 from July 2011

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Closes #13291
  • Loading branch information
nabijaczleweli authored and behlendorf committed Apr 20, 2022
1 parent dac0b07 commit eaf1e06
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 82 deletions.
92 changes: 68 additions & 24 deletions contrib/dracut/90zfs/mount-zfs.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,42 @@ fi
info "ZFS: No sysroot.mount exists or zfs-generator did not extend it."
info "ZFS: Mounting root with the traditional mount-zfs.sh instead."

# ask_for_password tries prompt cmd
#
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
# if plymouth is not present.
ask_for_password() {
tries="$1"
prompt="$2"
cmd="$3"

{
flock -s 9

# Prompt for password with plymouth, if installed and running.
if plymouth --ping 2>/dev/null; then
plymouth ask-for-password \
--prompt "$prompt" --number-of-tries="$tries" | \
eval "$cmd"
ret=$?
else
i=1
while [ "$i" -le "$tries" ]; do
printf "%s [%i/%i]:" "$prompt" "$i" "$tries" >&2
eval "$cmd" && ret=0 && break
ret=$?
i=$((i+1))
printf '\n' >&2
done
unset i
fi
} 9>/.console_lock

[ "$ret" -ne 0 ] && echo "Wrong password" >&2
return "$ret"
}


# Delay until all required block devices are present.
modprobe zfs 2>/dev/null
udevadm settle
Expand All @@ -45,31 +81,39 @@ fi
ZFS_DATASET="${ZFS_DATASET:-${root}}"
ZFS_POOL="${ZFS_DATASET%%/*}"

if import_pool "${ZFS_POOL}" ; then
# Load keys if we can or if we need to
if [ "$(zpool list -H -o feature@encryption "${ZFS_POOL}")" = 'active' ]; then
# if the root dataset has encryption enabled
ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${ZFS_DATASET}")"
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")"
# if the key needs to be loaded
if [ "$KEYSTATUS" = "unavailable" ]; then
# decrypt them
ask_for_password \
5 \
"Encrypted ZFS password for ${ENCRYPTIONROOT}: " \
"zfs load-key '${ENCRYPTIONROOT}'"
fi

if ! zpool get -Ho name "${ZFS_POOL}" > /dev/null 2>&1; then
info "ZFS: Importing pool ${ZFS_POOL}..."
# shellcheck disable=SC2086
if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${ZFS_POOL}"; then
warn "ZFS: Unable to import pool ${ZFS_POOL}"
rootok=0
return 1
fi
fi

# Load keys if we can or if we need to
if [ "$(zpool get -Ho value feature@encryption "${ZFS_POOL}")" = 'active' ]; then
# if the root dataset has encryption enabled
ENCRYPTIONROOT="$(zfs get -Ho value encryptionroot "${ZFS_DATASET}")"
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
KEYSTATUS="$(zfs get -Ho value keystatus "${ENCRYPTIONROOT}")"
# if the key needs to be loaded
if [ "$KEYSTATUS" = "unavailable" ]; then
# decrypt them
ask_for_password \
5 \
"Encrypted ZFS password for ${ENCRYPTIONROOT}: " \
"zfs load-key '${ENCRYPTIONROOT}'"
fi
fi
# Let us tell the initrd to run on shutdown.
# We have a shutdown hook to run
# because we imported the pool.
info "ZFS: Mounting dataset ${ZFS_DATASET}..."
if mount_dataset "${ZFS_DATASET}" ; then
ROOTFS_MOUNTED=yes
return 0
fi
fi

rootok=0
# Let us tell the initrd to run on shutdown.
# We have a shutdown hook to run
# because we imported the pool.
info "ZFS: Mounting dataset ${ZFS_DATASET}..."
if ! mount_dataset "${ZFS_DATASET}"; then
rootok=0
return 1
fi
62 changes: 4 additions & 58 deletions contrib/dracut/90zfs/zfs-lib.sh.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2034

command -v getarg >/dev/null || . /lib/dracut-lib.sh || . /usr/lib/dracut/modules.d/99base/dracut-lib.sh
command -v getargbool >/dev/null || {
Expand All @@ -16,34 +17,14 @@ command -v getargbool >/dev/null || {
}
}

OLDIFS="${IFS}"
NEWLINE="
"
TAB=" "

ZPOOL_IMPORT_OPTS=""
if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
ZPOOL_IMPORT_OPTS=
if getargbool 0 zfs_force -y zfs.force -y zfsforce; then
warn "ZFS: Will force-import pools if necessary."
ZPOOL_IMPORT_OPTS="${ZPOOL_IMPORT_OPTS} -f"
ZPOOL_IMPORT_OPTS=-f
fi

# import_pool POOL
# imports the given zfs pool if it isn't imported already.
import_pool() {
pool="${1}"

if ! zpool list -H "${pool}" > /dev/null 2>&1; then
info "ZFS: Importing pool ${pool}..."
# shellcheck disable=SC2086
if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${pool}" ; then
warn "ZFS: Unable to import pool ${pool}"
return 1
fi
fi

return 0
}

_mount_dataset_cb() {
# shellcheck disable=SC2154
mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}"
Expand Down Expand Up @@ -97,41 +78,6 @@ for_relevant_root_children() {
)
}

# ask_for_password tries prompt cmd
#
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
# if plymouth is not present.
ask_for_password() {
tries="$1"
prompt="$2"
cmd="$3"

{
flock -s 9

# Prompt for password with plymouth, if installed and running.
if plymouth --ping 2>/dev/null; then
plymouth ask-for-password \
--prompt "$prompt" --number-of-tries="$tries" | \
eval "$cmd"
ret=$?
else
i=1
while [ "$i" -le "$tries" ]; do
printf "%s [%i/%i]:" "$prompt" "$i" "$tries" >&2
eval "$cmd" && ret=0 && break
ret=$?
i=$((i+1))
printf '\n' >&2
done
unset i
fi
} 9>/.console_lock

[ "$ret" -ne 0 ] && echo "Wrong password" >&2
return "$ret"
}

# Parse root=, rootfstype=, return them decoded and normalised to zfs:AUTO for auto, plain dset for explicit
#
# True if ZFS-on-root, false if we shouldn't
Expand Down

0 comments on commit eaf1e06

Please sign in to comment.