~nabijaczleweli/tzpfms

fc7a47510637afa9ec903a516a857ab26213a127 — наб 23 days ago 24f59ec trunk
It's a disaster, but non-plymouth dracut kinda works
A initrd/dracut/module-setup.sh => initrd/dracut/module-setup.sh +66 -0
@@ 0,0 1,66 @@
#!/bin/sh
# SPDX-License-Identifier: MIT


# -h
# 0
# "$hostonly" set?
check() {
	command -v zfs-tpm-list > /dev/null || return 1

	# TODO: handle hostonly, proper only-include-if-all-found
	#command -v zfs-tpm2-load-key > /dev/null
	#command -v zfs-tpm1x-load-key > /dev/null

	return 0
}


depends() {
	echo zfs
	return 0
}


installkernel() {
	instmods '=drivers/char/tpm'
}


install() {
	dracut_install zfs-tpm-list
	dracut_install zfs-tpm2-load-key
	dracut_install zfs-tpm1x-load-key
	dracut_install tcsd

	inst_hook pre-mount 89 "${moddir:-}/tzpfms-load-key.sh"  # zfs installs with 90, we *must* run beforehand
	return 0

	inst_simple "${moddir:-}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
	if [ -e @sysconfdir@/zfs/zpool.cache ]; then
		inst @sysconfdir@/zfs/zpool.cache
		type mark_hostonly >/dev/null 2>&1 && mark_hostonly @sysconfdir@/zfs/zpool.cache
	fi

	if dracut_module_included "systemd"; then
		mkdir -p "${initdir:-}/${systemdsystemunitdir:-}/zfs-import.target.wants"
		for _item in scan cache ; do
			dracut_install @systemdunitdir@/zfs-import-$_item.service
			if ! [ -L "${initdir}/${systemdsystemunitdir:-}/zfs-import.target.wants"/zfs-import-$_item.service ]; then
				ln -s ../zfs-import-$_item.service "${initdir}/${systemdsystemunitdir:-}/zfs-import.target.wants"/zfs-import-$_item.service
				type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-import-$_item.service
			fi
		done
		inst "${moddir}"/zfs-env-bootfs.service "${systemdsystemunitdir:-}"/zfs-env-bootfs.service
		ln -s ../zfs-env-bootfs.service "${initdir}/${systemdsystemunitdir:-}/zfs-import.target.wants"/zfs-env-bootfs.service
		type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-env-bootfs.service
		dracut_install systemd-ask-password
		dracut_install systemd-tty-ask-password-agent
		mkdir -p "${initdir}/${systemdsystemunitdir:-}/initrd.target.wants"
		dracut_install @systemdunitdir@/zfs-import.target
		if ! [ -L "${initdir}/${systemdsystemunitdir:-}/initrd.target.wants"/zfs-import.target ]; then
			ln -s ../zfs-import.target "${initdir}/${systemdsystemunitdir:-}/initrd.target.wants"/zfs-import.target
			type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-import.target
		fi
	fi
}

A initrd/dracut/tzpfms-load-key.sh => initrd/dracut/tzpfms-load-key.sh +86 -0
@@ 0,0 1,86 @@
#!/bin/sh
# SPDX-License-Identifier: MIT


# Only run on systemd systems, mimicking zfs-dracut's zfs-load-key.sh, TODO: "see mount-zfs.sh for non-systemd systems"
[ -d /run/systemd ] || exit 0


. "/lib/dracut-lib.sh"


# If root is not "ZFS=" or "zfs:", or rootfstype is not "zfs" then we aren't supposed to handle it
root="${root:=$(getarg root=)}"
rootfstype="${rootfstype:=$(getarg rootfstype=)}"
[ "${root##zfs:}" = "$root" ] && [ "${root##ZFS=}" = "$root" ] && [ "$rootfstype" != "zfs" ] && exit 0


# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported
while [ "$(zpool list -H)" = "" ]; do
    sleep 0.1s
    systemctl is-failed --quiet zfs-import-cache.service zfs-import-scan.service && exit 1
done


if [ "$root" = "zfs:AUTO" ] ; then
    BOOTFS="$(zpool list -H -o bootfs | awk '!/^-$/ {print; exit}')"
else
    BOOTFS="${root##zfs:}"
    BOOTFS="${BOOTFS##ZFS=}"
fi


# This sucks a lot of ass, since we don't know the questions or the amount thereof beforehand
# (0-2 (owner hierarchy/ownership + sealed object, both optional) best-case and 0-6 worst-case (both entered wrong twice)).
# Plymouth doesn't allow us to actually check what the splash status was, and ioctl(KDGETMODE) isn't reliable;
# ideally, we'd only clear the screen if we were making the switch, but not if the user was already switched to the log output.
# Instead, clear if there's a "quiet", leave alone otherwise, and always restore;
# cmdline option "plymouth.ignore-show-splash" can be used to disable splashes altogether, if desired.
with_promptable_tty() {
    echo "$@" > /dev/console
    if command -v plymouth > /dev/null && plymouth --ping; then
        #plymouth hide-splash
        plymouth deactivate
        grep -q 'quiet' /proc/cmdline && printf '\033c'

        "$@" < /dev/console > /dev/console 2>&1; ret="$?"

        # TODO: some combination of all this does an absolute fucky wucky
        plymouth reactivate????
        #plymouth show-splash
    else
        # Mimic /scripts/zfs#decrypt_fs(): setting "printk" temporarily to "7" will allow prompt even if kernel option "quiet"
        printk="$(awk '{print $1}' /proc/sys/kernel/printk)"
        [ "$printk" = "7" ] || echo 7 > /proc/sys/kernel/printk

        "$@" < /dev/console > /dev/console 2>&1; ret="$?"

        [ "$printk" = "7" ] || echo 7 > /proc/sys/kernel/printk
    fi
    return "$ret"
}


# If pool encryption is active and the zfs command understands '-o encryption'
if [ "$(zpool list -H -o feature@encryption "$(echo "$BOOTFS" | awk -F/ '{print $1}')")" = "active" ]; then
    ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "$BOOTFS")"

    if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
        # Match this sexion to i-t/zfs-patch.sh
        if command -v zfs-tpm2-load-key > /dev/null && ! [ "$(zfs-tpm-list -Hub TPM2 "$ENCRYPTIONROOT")" = "" ]; then
            with_promptable_tty zfs-tpm2-load-key "$ENCRYPTIONROOT"
            exit
        fi

        if command -v zfs-tpm1x-load-key > /dev/null && ! [ "$(zfs-tpm-list -Hub TPM1.X "$ENCRYPTIONROOT")" = "" ]; then
            [ -z "$TZPFMS_TPM1X" ] && command -v tcsd > /dev/null && tcsd -f &
            with_promptable_tty zfs-tpm1x-load-key "$ENCRYPTIONROOT"; err="$?"
            [ -z "$TZPFMS_TPM1X" ] && command -v tcsd > /dev/null && kill %+
            exit "$err"
        fi

        # Fall through to zfs-dracut's zfs-load-key.sh
        with_promptable_tty zfs load-key "$ENCRYPTIONROOT"
        exit
    fi
fi

M initrd/initramfs-tools/zfs-patch.sh => initrd/initramfs-tools/zfs-patch.sh +4 -3
@@ 13,10 13,11 @@ decrypt_fs() {

	# First three lines borrowed from /scripts/zfs#decrypt_fs()
	# If pool encryption is active and the zfs command understands '-o encryption'
	if [ "$(zpool list -H -o feature@encryption "$(echo "${fs}" | awk -F/ '{print $1}')")" = 'active' ]; then
		ENCRYPTIONROOT="$(get_fs_value "${fs}" encryptionroot)"
	if [ "$(zpool list -H -o feature@encryption "$(echo "$fs" | awk -F/ '{print $1}')")" = "active" ]; then
		ENCRYPTIONROOT="$(get_fs_value "$fs" encryptionroot)"

		if ! [ "$ENCRYPTIONROOT" = "-" ]; then
			# Match this sexion to dracut/tzpfms-load-key.sh
			if command -v zfs-tpm2-load-key > /dev/null && ! [ "$(zfs-tpm-list -Hub TPM2 "$ENCRYPTIONROOT")" = "" ]; then
				with_promptable_tty zfs-tpm2-load-key "$ENCRYPTIONROOT"
				return


@@ 42,7 43,7 @@ decrypt_fs() {
# Plymouth doesn't allow us to actually check what the splash status was, and ioctl(KDGETMODE) isn't reliable;
# ideally, we'd only clear the screen if we were making the switch, but not if the user was already switched to the log output.
# Instead, clear if there's a "quiet", leave alone otherwise, and always restore;
# cmdline option "plymouth.ignore-show-splash" can be used to disable splashes alltogether, if desired.
# cmdline option "plymouth.ignore-show-splash" can be used to disable splashes altogether, if desired.
with_promptable_tty() {
	if command -v plymouth > /dev/null && plymouth --ping; then
		plymouth hide-splash