]> code.ossystems Code Review - openembedded-core.git/commitdiff
initramfs-framework: add retry loop for slow boot devices (like USB)
authorPatrick Ohly <patrick.ohly@intel.com>
Fri, 1 Jul 2016 13:53:51 +0000 (15:53 +0200)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Fri, 8 Jul 2016 08:55:41 +0000 (09:55 +0100)
On some hardware platforms (Gigabyte, qemu), detection of USB devices
by the kernel is slow enough such that it happens only after the first
attempt to mount the rootfs. We need to keep trying for a while
(default: 5s seconds, controlled by roottimeout=<seconds>) and sleep
between each attempt (default: one second, rootdelay=<seconds>).

This change intentionally splits finding the rootfs (in the new
"rootfs") and switching to it ("finish"). That is needed to keep udev
running while waiting for the rootfs, because it shuts down before
"finish" starts. It is also the direction that was discussed on the OE
mailing list for future changes to initramfs-framework (like
supporting a "live CD" module, which would replace or further augment
mounting of the rootfs).

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
meta/recipes-core/initrdscripts/initramfs-framework/finish
meta/recipes-core/initrdscripts/initramfs-framework/rootfs [new file with mode: 0644]
meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb

index d09bbb8bed4dfd8eae29b2152e4857a054e31641..717383ebac830fc8ce37ee45d8c4f389557567a5 100755 (executable)
@@ -8,39 +8,6 @@ finish_enabled() {
 
 finish_run() {
        if [ -n "$ROOTFS_DIR" ]; then
-               if [ -n "$bootparam_rootdelay" ]; then
-                       debug "Sleeping for $rootdelay second(s) to wait root to settle..."
-                       sleep $bootparam_rootdelay
-               fi
-
-               if [ -n "$bootparam_root" ]; then
-                       debug "No e2fs compatible filesystem has been mounted, mounting $bootparam_root..."
-
-                       if [ "`echo ${bootparam_root} | cut -c1-5`" = "UUID=" ]; then
-                               root_uuid=`echo $bootparam_root | cut -c6-`
-                               bootparam_root="/dev/disk/by-uuid/$root_uuid"
-                       fi
-
-                       if [ -e "$bootparam_root" ]; then
-                               flags=""
-                               if [ -n "$bootparam_ro" ]; then
-                                       if [  -n "$bootparam_rootflags" ]; then
-                                               bootparam_rootflags="$bootparam_rootflags,"
-                                       fi
-                                       bootparam_rootflags="${bootparam_rootflags}ro"
-                               fi
-                               if [ -n "$bootparam_rootflags" ]; then
-                                       flags="$flags -o$bootparam_rootflags"
-                               fi
-                               if [ -n "$bootparam_rootfstype" ]; then
-                                       flags="$flags -t$bootparam_rootfstype"
-                               fi
-                               mount $flags $bootparam_root $ROOTFS_DIR
-                       else
-                               msg "root '$bootparam_root' doesn't exist."
-                       fi
-               fi
-
                if [ ! -d $ROOTFS_DIR/dev ]; then
                        fatal "ERROR: There's no '/dev' on rootfs."
                fi
diff --git a/meta/recipes-core/initrdscripts/initramfs-framework/rootfs b/meta/recipes-core/initrdscripts/initramfs-framework/rootfs
new file mode 100644 (file)
index 0000000..5790d8c
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+# Copyright (C) 2011 O.S. Systems Software LTDA.
+# Licensed on MIT
+
+rootfs_enabled() {
+       return 0
+}
+
+rootfs_run() {
+        if [ -z "$ROOTFS_DIR" ]; then
+               return
+        fi
+       C=0
+       delay=${bootparam_rootdelay:-1}
+       timeout=${bootparam_roottimeout:-5}
+       while [ ! -d $ROOTFS_DIR/dev ]; do
+               if [ $(( $C * $delay )) -gt $timeout ]; then
+                       fatal "root '$bootparam_root' doesn't exist or does not contain a /dev."
+               fi
+
+               if [ -n "$bootparam_root" ]; then
+                       debug "No e2fs compatible filesystem has been mounted, mounting $bootparam_root..."
+
+                       if [ "`echo ${bootparam_root} | cut -c1-5`" = "UUID=" ]; then
+                               root_uuid=`echo $bootparam_root | cut -c6-`
+                               bootparam_root="/dev/disk/by-uuid/$root_uuid"
+                       fi
+
+                       if [ -e "$bootparam_root" ]; then
+                               flags=""
+                               if [ -n "$bootparam_ro" ] && ! echo "$bootparam_rootflags" | grep -w -q "ro"; then
+                                       if [  -n "$bootparam_rootflags" ]; then
+                                               bootparam_rootflags="$bootparam_rootflags,"
+                                       fi
+                                       bootparam_rootflags="${bootparam_rootflags}ro"
+                               fi
+                               if [ -n "$bootparam_rootflags" ]; then
+                                       flags="$flags -o$bootparam_rootflags"
+                               fi
+                               if [ -n "$bootparam_rootfstype" ]; then
+                                       flags="$flags -t$bootparam_rootfstype"
+                               fi
+                               mount $flags $bootparam_root $ROOTFS_DIR
+                               if [ -d $ROOTFS_DIR/dev ]; then
+                                       break
+                               else
+                                       # It is unlikely to change, but keep trying anyway.
+                                       # Perhaps we pick a different device next time.
+                                       umount $ROOTFS_DIR
+                                       fi
+                               fi
+               fi
+               debug "Sleeping for $delay second(s) to wait root to settle..."
+               sleep $delay
+               C=$(( $C + 1 ))
+       done
+}
index e5cf9cb4dd0a21f284a01160af8baf4c8a92cbf2..89e153d3487a5244a17ef509426aa69940a85783 100644 (file)
@@ -8,6 +8,7 @@ PR = "r2"
 inherit allarch
 
 SRC_URI = "file://init \
+           file://rootfs \
            file://finish \
            file://mdev \
            file://udev \
@@ -21,6 +22,7 @@ do_install() {
 
     # base
     install -m 0755 ${WORKDIR}/init ${D}/init
+    install -m 0755 ${WORKDIR}/rootfs ${D}/init.d/90-rootfs
     install -m 0755 ${WORKDIR}/finish ${D}/init.d/99-finish
 
     # mdev
@@ -47,7 +49,7 @@ PACKAGES = "${PN}-base \
             initramfs-module-e2fs \
             initramfs-module-debug"
 
-FILES_${PN}-base = "/init /init.d/99-finish /dev"
+FILES_${PN}-base = "/init /init.d/90-rootfs /init.d/99-finish /dev"
 
 SUMMARY_initramfs-module-mdev = "initramfs support for mdev"
 RDEPENDS_initramfs-module-mdev = "${PN}-base busybox-mdev"