Commit cc1ed7542c8c26af0f501da8006b9fce03e9aaca

Authored by Pierre Ossman
Committed by Linus Torvalds
1 parent 4a19542e5f

init: wait for asynchronously scanned block devices

Some buses (e.g.  USB and MMC) do their scanning of devices in the
background, causing a race between them and prepare_namespace().  In order
to be able to use these buses without an initrd, we now wait for the device
specified in root= to actually show up.

If the device never shows up than we will hang in an infinite loop.  In
order to not mess with setups that reboot on panic, the feature must be
turned on via the command line option "rootwait".

[bunk@stusta.de: root_wait can become static]
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 26 additions and 2 deletions Side-by-side Diff

Documentation/kernel-parameters.txt
... ... @@ -1504,6 +1504,10 @@
1504 1504  
1505 1505 rootfstype= [KNL] Set root filesystem type
1506 1506  
  1507 + rootwait [KNL] Wait (indefinitely) for root device to show up.
  1508 + Useful for devices that are detected asynchronously
  1509 + (e.g. USB and MMC devices).
  1510 +
1507 1511 rw [KNL] Mount root device read-write on boot
1508 1512  
1509 1513 S [KNL] Run init in single mode
... ... @@ -25,6 +25,7 @@
25 25 int root_mountflags = MS_RDONLY | MS_SILENT;
26 26 char * __initdata root_device_name;
27 27 static char __initdata saved_root_name[64];
  28 +static int __initdata root_wait;
28 29  
29 30 dev_t ROOT_DEV;
30 31  
... ... @@ -216,6 +217,16 @@
216 217  
217 218 __setup("root=", root_dev_setup);
218 219  
  220 +static int __init rootwait_setup(char *str)
  221 +{
  222 + if (*str)
  223 + return 0;
  224 + root_wait = 1;
  225 + return 1;
  226 +}
  227 +
  228 +__setup("rootwait", rootwait_setup);
  229 +
219 230 static char * __initdata root_mount_data;
220 231 static int __init root_data_setup(char *str)
221 232 {
222 233  
... ... @@ -438,10 +449,19 @@
438 449 root_device_name += 5;
439 450 }
440 451  
441   - is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
442   -
443 452 if (initrd_load())
444 453 goto out;
  454 +
  455 + /* wait for any asynchronous scanning to complete */
  456 + if ((ROOT_DEV == 0) && root_wait) {
  457 + printk(KERN_INFO "Waiting for root device %s...\n",
  458 + saved_root_name);
  459 + while (driver_probe_done() != 0 ||
  460 + (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
  461 + msleep(100);
  462 + }
  463 +
  464 + is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
445 465  
446 466 if (is_floppy && rd_doload && rd_load_disk(0))
447 467 ROOT_DEV = Root_RAM0;