The root-only udev path can resolve root=LABEL= before the storage
device has registered. This makes the lookup fail and causes an
unnecessary full udev coldplug.

Retry the lookup five times with a 10 ms delay before falling back to
the existing full coldplug path.

Fixes: fda394c2b91b ("initramfs-framework: support LABEL with root-only udev 
trigger")
Signed-off-by: Wenwen Fu <[email protected]>
---
 .../initrdscripts/initramfs-framework/udev    | 33 +++++++++++++++----
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/udev 
b/meta/recipes-core/initrdscripts/initramfs-framework/udev
index 85c5ba1178..fbf1b98d56 100644
--- a/meta/recipes-core/initrdscripts/initramfs-framework/udev
+++ b/meta/recipes-core/initrdscripts/initramfs-framework/udev
@@ -35,6 +35,31 @@ udev_enabled() {
        return 0
 }
 
+udev_resolve_root_label() {
+       udev_root_label=$1
+       udev_root_label_retries_left=5
+       udev_root_partuuid=
+
+       # The block device may still be registering when initramfs starts.
+       # Retry up to five times after the initial lookup, with a 10 ms delay,
+       # before falling back to a full udev coldplug.
+       while :; do
+               udev_root_dev=$(findfs "LABEL=$udev_root_label" 2>/dev/null)
+               if [ -n "$udev_root_dev" ]; then
+                       udev_root_partuuid=$(sed -n 's/^PARTUUID=//p' \
+                               
"/sys/class/block/${udev_root_dev#/dev/}/uevent" 2>/dev/null)
+                       [ -n "$udev_root_partuuid" ] && break
+               fi
+               [ "$udev_root_label_retries_left" -eq 0 ] && break
+               udev_root_label_retries_left=$((udev_root_label_retries_left - 
1))
+               sleep 0.01
+       done
+
+       [ -n "$udev_root_partuuid" ] || return 1
+       root_match="PARTUUID=$udev_root_partuuid"
+       return 0
+}
+
 udev_trigger_root_device() {
        case "${bootparam_root:-}" in
                PARTLABEL=?*)
@@ -47,13 +72,7 @@ udev_trigger_root_device() {
                        # The kernel does not export the filesystem LABEL in the
                        # uevent, so resolve it to a device node with findfs and
                        # match on that device's kernel-provided PARTUUID.
-                       root_label="${bootparam_root#LABEL=}"
-                       root_dev=$(findfs "LABEL=$root_label" 2>/dev/null) || 
return 1
-                       [ -n "$root_dev" ] || return 1
-                       root_partuuid=$(sed -n 's/^PARTUUID=//p' \
-                               "/sys/class/block/${root_dev#/dev/}/uevent" 
2>/dev/null)
-                       [ -n "$root_partuuid" ] || return 1
-                       root_match="PARTUUID=$root_partuuid"
+                       udev_resolve_root_label "${bootparam_root#LABEL=}" || 
return 1
                        ;;
                *)
                        return 1
-- 
2.43.0

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#246458): 
https://lists.openembedded.org/g/openembedded-core/message/246458
Mute This Topic: https://lists.openembedded.org/mt/121389207/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to