From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Mon, 9 Jan 2023 11:47:06 +0100 Subject: [PATCH 1/4] fix(dracut-systemd): remove unused argument The `generator_wait_for_dev` function of the dracut rootfs systemd generator only uses the first argument. Moreover, RDRETRY is unset at this point. (cherry picked from commit eb75861c2a1c05eb142616da1891a7fa5a2a34e1) --- modules.d/98dracut-systemd/rootfs-generator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh index e1d365df..3238b495 100755 --- a/modules.d/98dracut-systemd/rootfs-generator.sh +++ b/modules.d/98dracut-systemd/rootfs-generator.sh @@ -104,7 +104,7 @@ esac GENERATOR_DIR="$1" if [ "$rootok" = "1" ]; then - generator_wait_for_dev "${root#block:}" "$RDRETRY" + generator_wait_for_dev "${root#block:}" generator_fsck_after_pre_mount "${root#block:}" strstr "$(cat /proc/cmdline)" 'root=' || generator_mount_rootfs "${root#block:}" "$(getarg rootfstype=)" "$(getarg rootflags=)" fi -- 2.39.2 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Wed, 1 Mar 2023 11:21:16 +0100 Subject: [PATCH 2/4] fix(dracut-systemd): do not hardcode the systemd generator directory The normal directory is the first argument passed to the systemd generator, so use it instead of hardcoding /run/systemd/generator. (cherry picked from commit a2b32ed976898188bc98d9b6c7eec3dc45f4abf0) --- modules.d/98dracut-systemd/rootfs-generator.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh index 3238b495..5b85d8c5 100755 --- a/modules.d/98dracut-systemd/rootfs-generator.sh +++ b/modules.d/98dracut-systemd/rootfs-generator.sh @@ -17,7 +17,7 @@ generator_wait_for_dev() { # after remote-fs-pre.target since the initqueue is ordered before it so # it will never actually show up (think Tang-pinned rootfs). cat > "$hookdir/initqueue/finished/devexists-${_name}.sh" << EOF -if ! grep -q After=remote-fs-pre.target /run/systemd/generator/systemd-cryptsetup@*.service 2>/dev/null; then +if ! grep -q After=remote-fs-pre.target "$GENERATOR_DIR"/systemd-cryptsetup@*.service 2>/dev/null; then [ -e "$1" ] fi EOF @@ -77,12 +77,12 @@ generator_fsck_after_pre_mount() { [ -z "$1" ] && return 0 _name=$(dev_unit_name "$1") - [ -d /run/systemd/generator/systemd-fsck@"${_name}".service.d ] || mkdir -p /run/systemd/generator/systemd-fsck@"${_name}".service.d - if ! [ -f /run/systemd/generator/systemd-fsck@"${_name}".service.d/after-pre-mount.conf ]; then + [ -d "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d ] || mkdir -p "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d + if ! [ -f "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d/after-pre-mount.conf ]; then { echo "[Unit]" echo "After=dracut-pre-mount.service" - } > /run/systemd/generator/systemd-fsck@"${_name}".service.d/after-pre-mount.conf + } > "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d/after-pre-mount.conf fi } -- 2.39.2 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Wed, 1 Mar 2023 12:07:29 +0100 Subject: [PATCH 3/4] fix(dracut-systemd): check and create generator dir outside of inner function (cherry picked from commit e21f8f7d5abaae37ada8c7a6dc91c2d878e0b501) --- modules.d/98dracut-systemd/rootfs-generator.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh index 5b85d8c5..c3f60ad4 100755 --- a/modules.d/98dracut-systemd/rootfs-generator.sh +++ b/modules.d/98dracut-systemd/rootfs-generator.sh @@ -51,7 +51,6 @@ generator_mount_rootfs() { [ -z "$1" ] && return 0 _name=$(dev_unit_name "$1") - [ -d "$GENERATOR_DIR" ] || mkdir -p "$GENERATOR_DIR" if ! [ -f "$GENERATOR_DIR"/sysroot.mount ]; then { echo "[Unit]" @@ -101,9 +100,11 @@ case "${root#block:}" in ;; esac -GENERATOR_DIR="$1" - if [ "$rootok" = "1" ]; then + GENERATOR_DIR="$1" + [ -z "$GENERATOR_DIR" ] && exit 1 + [ -d "$GENERATOR_DIR" ] || mkdir -p "$GENERATOR_DIR" + generator_wait_for_dev "${root#block:}" generator_fsck_after_pre_mount "${root#block:}" strstr "$(cat /proc/cmdline)" 'root=' || generator_mount_rootfs "${root#block:}" "$(getarg rootfstype=)" "$(getarg rootflags=)" -- 2.39.2 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Antonio Alvarez Feijoo Date: Fri, 3 Mar 2023 16:06:30 +0100 Subject: [PATCH 4/4] fix(dracut-systemd): rootfs-generator cannot write outside of generator dir Altough it was already documented in systemd.generator(7) that generators must not write to locations other than those passed as arguments, since https://github.com/systemd/systemd/commit/ca6ce62d systemd executes generators in a mount namespace "sandbox", so now the hooks created by the rootfs-generator are lost. These hooks are created using the root= cmdline argument, so this patch moves the creation of these hooks to a cmdline hook. Fixes issue #2211 Fixes issue #2225 (cherry picked from commit 4bde75fabe31a5c048fd75e533b94e91c3faa83b) --- modules.d/98dracut-systemd/module-setup.sh | 2 + .../98dracut-systemd/parse-root.sh (new +x) | 38 +++++++++++++++++++ .../98dracut-systemd/rootfs-generator.sh | 20 +--------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/modules.d/98dracut-systemd/module-setup.sh b/modules.d/98dracut-systemd/module-setup.sh index b7da86db..e66fc956 100755 --- a/modules.d/98dracut-systemd/module-setup.sh +++ b/modules.d/98dracut-systemd/module-setup.sh @@ -37,6 +37,8 @@ install() { inst_script "$moddir/rootfs-generator.sh" "$systemdutildir"/system-generators/dracut-rootfs-generator + inst_hook cmdline 10 "$moddir/parse-root.sh" + for i in \ dracut-cmdline.service \ dracut-cmdline-ask.service \ diff --git a/modules.d/98dracut-systemd/parse-root.sh b/modules.d/98dracut-systemd/parse-root.sh new file mode 100755 index 00000000..deeeff3f --- /dev/null +++ b/modules.d/98dracut-systemd/parse-root.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +root=$(getarg root=) +case "${root#block:}" in + LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*) + root="block:$(label_uuid_to_dev "$root")" + rootok=1 + ;; + /dev/nfs) # ignore legacy /dev/nfs + ;; + /dev/*) + root="block:${root}" + rootok=1 + ;; +esac + +if [ "$rootok" = "1" ]; then + root_dev="${root#block:}" + root_name="$(str_replace "$root_dev" '/' '\x2f')" + if ! [ -e "$hookdir/initqueue/finished/devexists-${root_name}.sh" ]; then + + # If a LUKS device needs unlocking via systemd in the initrd, assume + # it's for the root device. In that case, don't block on it if it's + # after remote-fs-pre.target since the initqueue is ordered before it so + # it will never actually show up (think Tang-pinned rootfs). + cat > "$hookdir/initqueue/finished/devexists-${root_name}.sh" << EOF +if ! grep -q After=remote-fs-pre.target /run/systemd/generator/systemd-cryptsetup@*.service 2>/dev/null; then + [ -e "$root_dev" ] +fi +EOF + { + printf '[ -e "%s" ] || ' "$root_dev" + printf 'warn "\"%s\" does not exist"\n' "$root_dev" + } >> "$hookdir/emergency/80-${root_name}.sh" + fi +fi diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh index c3f60ad4..bcfd2b89 100755 --- a/modules.d/98dracut-systemd/rootfs-generator.sh +++ b/modules.d/98dracut-systemd/rootfs-generator.sh @@ -6,28 +6,10 @@ generator_wait_for_dev() { local _name local _timeout - _name="$(str_replace "$1" '/' '\x2f')" + _name=$(dev_unit_name "$1") _timeout=$(getarg rd.timeout) _timeout=${_timeout:-0} - if ! [ -e "$hookdir/initqueue/finished/devexists-${_name}.sh" ]; then - - # If a LUKS device needs unlocking via systemd in the initrd, assume - # it's for the root device. In that case, don't block on it if it's - # after remote-fs-pre.target since the initqueue is ordered before it so - # it will never actually show up (think Tang-pinned rootfs). - cat > "$hookdir/initqueue/finished/devexists-${_name}.sh" << EOF -if ! grep -q After=remote-fs-pre.target "$GENERATOR_DIR"/systemd-cryptsetup@*.service 2>/dev/null; then - [ -e "$1" ] -fi -EOF - { - printf '[ -e "%s" ] || ' "$1" - printf 'warn "\"%s\" does not exist"\n' "$1" - } >> "$hookdir/emergency/80-${_name}.sh" - fi - - _name=$(dev_unit_name "$1") if ! [ -L "$GENERATOR_DIR"/initrd.target.wants/"${_name}".device ]; then [ -d "$GENERATOR_DIR"/initrd.target.wants ] || mkdir -p "$GENERATOR_DIR"/initrd.target.wants ln -s ../"${_name}".device "$GENERATOR_DIR"/initrd.target.wants/"${_name}".device -- 2.39.2