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