CHROMIUM: make dm= boot path wait for devices
authorWill Drewry <wad@chromium.org>
Fri, 23 Jul 2010 17:33:12 +0000 (12:33 -0500)
committerOlof Johansson <olof@lixom.net>
Fri, 1 Jun 2012 06:59:29 +0000 (23:59 -0700)
Prior to configuring mapped drives, we attempted to pre-resolve devices
out of the table configurations using the same logic as the other init
code.  However, like md, this may occur before devices are available.

This means that dm booting to a USB device will likely fail.  This
change adds root_wait-style code during device name resolution.  If the
device is not present, then the system will be blocked anyway.  If it
resolves after some period, then we can proceed. If the device resolves
immediately, then we never use this code.

It's worth noting that this will NOT wait for major:minor specified
devices.  I think that's probably okay, but it could be added if it makes
sense.  (forking this off to a separate function which rewalks looking for
' /dev/' or  ' digit*:digit* ')

Signed-off-by: Will Drewry <wad@chromium.org>
TEST=built a kernel and booted a verified rootfs off of usb with it
BUG=chromium-os:327

Change-Id: I350b4deceeeff3c499b4c3e00e4d7ae0645f8b16

Review URL: http://codereview.chromium.org/3059004

init/do_mounts_dm.c

index 0fd3411..ef0c58a 100644 (file)
@@ -5,6 +5,7 @@
  *
  * This file is released under the GPL.
  */
+#include <linux/async.h>
 #include <linux/device-mapper.h>
 #include <linux/fs.h>
 #include <linux/string.h>
@@ -182,9 +183,21 @@ static void __init dm_substitute_devices(char *str, size_t str_len)
                DMDEBUG("converting candidate device '%s' to dev_t", candidate);
                /* Use the boot-time specific device naming */
                dev = name_to_dev_t(candidate);
-               *candidate_end = old_char;
 
+               /* If it failed, but the candidate starts with /dev/, then try
+                * after device probing ends.
+                */
+               if (!dev && strncmp(candidate, "/dev/", 5) == 0) {
+                       DMINFO("waiting to resolve device '%s'...",
+                              candidate);
+                       while (driver_probe_done() != 0 ||
+                               (dev = name_to_dev_t(candidate)) == 0)
+                               msleep(100);
+                       async_synchronize_full();
+               }
                DMDEBUG(" -> %u", dev);
+
+               *candidate_end = old_char;
                /* No suitable replacement found */
                if (!dev)
                        continue;