ffd055
From 1e7a27bd5f463409392d34816a10bf108ee896c6 Mon Sep 17 00:00:00 2001
ffd055
From: Jonathan Lebon <jonathan@jlebon.com>
ffd055
Date: Fri, 9 Oct 2020 19:44:35 -0400
ffd055
Subject: [PATCH] 98dracut-systemd: don't wait for root device if remote
ffd055
 cryptsetup active
ffd055
ffd055
This is a plain and simple hack around dependency issues between dracut
ffd055
and systemd.
ffd055
ffd055
When using Tang-pinned LUKS root devices, we want to rely on
ffd055
`systemd-cryptsetup@.service` to unlock it. However, that service only
ffd055
runs `After=remote-fs-pre.target`, while `dracut-initqueue.service` has
ffd055
`Before=remote-fs-pre.target` (which makes sense because we don't want
ffd055
to attempt networked root devices before networking is up).
ffd055
ffd055
However, the rootfs-generator here wants to make sure that the root
ffd055
device exists *before* exiting the initqueue via an initqueue/finished
ffd055
"devexists" hook. This will never work though because by design
ffd055
`systemd-cryptsetup@.service`, which unlocks the root device, won't run
ffd055
until after we exit.
ffd055
ffd055
So we have a dependency cycle:
ffd055
ffd055
    initqueue -> devexists hook -> root device ->
ffd055
        systemd-cryptsetup@.service -> remote-fs-pre.target -> initqueue
ffd055
ffd055
There's no clean way to break this. The root issue is that there's no
ffd055
way right now to split sequencing of systemd services across the
ffd055
initqueue/online and initqueue/finished events because it's all bundled
ffd055
in a single service. (The deeper root issue of course is that we have
ffd055
two init systems. :) ).
ffd055
ffd055
Here we do a tactical fix: if there's a `systemd-cryptsetup@.service`
ffd055
instance, let's assume it's for the root device and skip waiting for it
ffd055
to show up if it depends on `remote-fs-pre.target`.
ffd055
ffd055
(cherry picked from commit 512c51d2677dd1637cc203e3676fefb50a3d73d0)
ffd055
ffd055
Resolves: #1897384
ffd055
---
ffd055
 modules.d/98dracut-systemd/rootfs-generator.sh | 11 +++++++++--
ffd055
 1 file changed, 9 insertions(+), 2 deletions(-)
ffd055
ffd055
diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh
ffd055
index 4ae693bb..bb376c0f 100755
ffd055
--- a/modules.d/98dracut-systemd/rootfs-generator.sh
ffd055
+++ b/modules.d/98dracut-systemd/rootfs-generator.sh
ffd055
@@ -13,8 +13,15 @@ generator_wait_for_dev()
ffd055
 
ffd055
     if ! [ -e "$hookdir/initqueue/finished/devexists-${_name}.sh" ]; then
ffd055
 
ffd055
-        printf '[ -e "%s" ]\n' $1 \
ffd055
-            >> "$hookdir/initqueue/finished/devexists-${_name}.sh"
ffd055
+        # If a LUKS device needs unlocking via systemd in the initrd, assume
ffd055
+        # it's for the root device. In that case, don't block on it if it's
ffd055
+        # after remote-fs-pre.target since the initqueue is ordered before it so
ffd055
+        # it will never actually show up (think Tang-pinned rootfs).
ffd055
+        cat > "$hookdir/initqueue/finished/devexists-${_name}.sh" << EOF
ffd055
+if ! grep -q After=remote-fs-pre.target /run/systemd/generator/systemd-cryptsetup@*.service 2>/dev/null; then
ffd055
+    [ -e "$1" ]
ffd055
+fi
ffd055
+EOF
ffd055
         {
ffd055
             printf '[ -e "%s" ] || ' $1
ffd055
             printf 'warn "\"%s\" does not exist"\n' $1
ffd055