Blob Blame Raw
From 2a82ba4040c8dc10dcbe7e2c3ae6646c2778f0b1 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
Date: Tue, 16 Jan 2018 13:29:54 -0500
Subject: [PATCH] Retry until success during systemd boot

With dracut, we just try once because we're being called in a loop. But with
systemd, there might be a race condition for network to come up. So when
running under systemd, we loop until success. This should not change the dracut
behavior.
---
 src/systemd/clevis-luks-askpass            | 66 ++++++++++++++++++++----------
 src/systemd/clevis-luks-askpass.service.in |  2 +-
 2 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/src/systemd/clevis-luks-askpass b/src/systemd/clevis-luks-askpass
index 2fadd5c..6fe5269 100755
--- a/src/systemd/clevis-luks-askpass
+++ b/src/systemd/clevis-luks-askpass
@@ -23,26 +23,50 @@ UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
 
 shopt -s nullglob
 
-for question in /run/systemd/ask-password/ask.*; do
-    d=
-    s=
-
-    while read line; do
-        case "$line" in
-            Id=cryptsetup:*) d="${line##Id=cryptsetup:}";;
-            Socket=*) s="${line##Socket=}";;
-        esac
-    done < "$question"
-
-    [ -z "$d" -o -z "$s" ] && continue
-
-    luksmeta show -d "$d" | while read -r slot state uuid; do
-        [ "$state" != "active" ] && continue
-        [ "$uuid" != "$UUID" ] && continue
-
-        if pt="`luksmeta load -d $d -s $slot -u $UUID | clevis decrypt`"; then
-            echo -n "+$pt" | nc -U -u --send-only "$s"
-            break
-        fi
+while getopts ":l" o; do
+    case "$o" in
+    l) loop=true;;
+    esac
+done
+
+while true; do
+    todo=0
+
+    for question in /run/systemd/ask-password/ask.*; do
+        metadata=false
+        unlocked=false
+        d=
+        s=
+
+        while read line; do
+            case "$line" in
+                Id=cryptsetup:*) d="${line##Id=cryptsetup:}";;
+                Socket=*) s="${line##Socket=}";;
+            esac
+        done < "$question"
+
+        [ -z "$d" -o -z "$s" ] && continue
+
+        while read -r slot state uuid; do
+            [ "$state" != "active" ] && continue
+            [ "$uuid" != "$UUID" ] && continue
+            metadata=true
+
+            if pt="`luksmeta load -d $d -s $slot -u $UUID | clevis decrypt`"; then
+                echo -n "+$pt" | nc -U -u --send-only "$s"
+                unlocked=true
+                break
+            fi
+        done < <(luksmeta show -d "$d")
+
+        [ $metadata == true ] || continue
+        [ $unlocked == true ] && continue
+        todo=$((todo + 1))
     done
+
+    if [ $todo -eq 0 ] || [ "$loop" != "true" ]; then
+        break;
+    fi
+
+    sleep 0.5
 done
diff --git a/src/systemd/clevis-luks-askpass.service.in b/src/systemd/clevis-luks-askpass.service.in
index aa38a5b..2c6bbed 100644
--- a/src/systemd/clevis-luks-askpass.service.in
+++ b/src/systemd/clevis-luks-askpass.service.in
@@ -5,4 +5,4 @@ After=network-online.target
 
 [Service]
 Type=oneshot
-ExecStart=@libexecdir@/clevis-luks-askpass
+ExecStart=@libexecdir@/clevis-luks-askpass -l
-- 
2.14.3