Thomas Chmielewski wrote:
> These all unpleasant tasks could be avoided if it was possible to have a 
> "fallback" device. For example, consider this hypothetical command line:
> 
> root=/dev/sdb1,/dev/sda1

Here is a patch to do this, though it sounds like you might have other
solutions.

This patch is for 2.6.18.1--thanks to Ed Falk for updating my original
2.6.11 patch.  If people are interested I can update and test this on
the current kernel.  It was tested on 2.6.11.

Please CC me with any comments.

-- Al


diff -uprN linux-2.6.18.1/init/do_mounts.c comma_root/init/do_mounts.c
--- linux-2.6.18.1/init/do_mounts.c     2006-10-13 20:34:03.000000000 -0700
+++ comma_root/init/do_mounts.c 2006-11-17 16:22:14.000000000 -0800
@@ -280,8 +280,9 @@ static int __init do_mount_root(char *na
        return 0;
 }
 
-void __init mount_block_root(char *name, int flags)
+static int __init mount_block_root_try(char *name, int flags)
 {
+       int err;
        char *fs_names = __getname();
        char *p;
        char b[BDEVNAME_SIZE];
@@ -289,7 +290,7 @@ void __init mount_block_root(char *name,
        get_fs_names(fs_names);
 retry:
        for (p = fs_names; *p; p += strlen(p)+1) {
-               int err = do_mount_root(name, p, flags, root_mount_data);
+               err = do_mount_root(name, p, flags, root_mount_data);
                switch (err) {
                        case 0:
                                goto out;
@@ -307,19 +308,33 @@ retry:
                printk("VFS: Cannot open root device \"%s\" or %s\n",
                                root_device_name, b);
                printk("Please append a correct \"root=\" boot option\n");
-
-               panic("VFS: Unable to mount root fs on %s", b);
        }
 
        printk("No filesystem could mount root, tried: ");
        for (p = fs_names; *p; p += strlen(p)+1)
                printk(" %s", p);
        printk("\n");
-       panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
+
+       err = -1;
 out:
        putname(fs_names);
+       return err;
 }
- 
+
+static inline void __init mount_block_root_fail(void)
+{
+       char b[BDEVNAME_SIZE];
+
+       panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
+}
+
+void __init mount_block_root(char *name, int flags)
+{
+       if (mount_block_root_try(name, flags) != 0)
+               mount_block_root_fail();
+}
+
+
 #ifdef CONFIG_ROOT_NFS
 static int __init mount_nfs_root(void)
 {
@@ -363,12 +378,12 @@ void __init change_floppy(char *fmt, ...
 }
 #endif
 
-void __init mount_root(void)
+static int __init mount_root_try(void)
 {
 #ifdef CONFIG_ROOT_NFS
        if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
                if (mount_nfs_root())
-                       return;
+                       return 0;
 
                printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying 
floppy.\n");
                ROOT_DEV = Root_FD0;
@@ -387,7 +402,18 @@ void __init mount_root(void)
        }
 #endif
        create_dev("/dev/root", ROOT_DEV);
-       mount_block_root("/dev/root", root_mountflags);
+       return mount_block_root_try("/dev/root", root_mountflags);
+}
+
+static inline void __init mount_root_fail(void)
+{
+       mount_block_root_fail();
+}
+
+void __init mount_root(void)
+{
+       if (mount_root_try() != 0)
+               mount_root_fail();
 }
 
 /*
@@ -396,6 +422,7 @@ void __init mount_root(void)
 void __init prepare_namespace(void)
 {
        int is_floppy;
+       char *p,*pnext;
 
        if (root_delay) {
                printk(KERN_INFO "Waiting %dsec before mounting root 
device...\n",
@@ -405,27 +432,36 @@ void __init prepare_namespace(void)
 
        md_run_setup();
 
-       if (saved_root_name[0]) {
-               root_device_name = saved_root_name;
+       for (p=saved_root_name; p && *p; p=pnext) {
+               pnext = strchr(p, ',');
+               if (pnext)
+                       *pnext++ = '\0';
+               root_device_name = p;
                if (!strncmp(root_device_name, "mtd", 3)) {
                        mount_block_root(root_device_name, root_mountflags);
                        goto out;
                }
                ROOT_DEV = name_to_dev_t(root_device_name);
+               if (ROOT_DEV == (dev_t)0)
+                       continue;
                if (strncmp(root_device_name, "/dev/", 5) == 0)
                        root_device_name += 5;
-       }
 
-       is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
+               is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
 
-       if (initrd_load())
-               goto out;
+               if (initrd_load())
+                       goto out;
 
-       if (is_floppy && rd_doload && rd_load_disk(0))
-               ROOT_DEV = Root_RAM0;
+               if (is_floppy && rd_doload && rd_load_disk(0))
+                       ROOT_DEV = Root_RAM0;
 
-       mount_root();
+               if (mount_root_try() == 0)
+                       goto out;
+
+       }
+       mount_root_fail();
 out:
+       sys_unlink("/initrd.image");
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
        sys_chroot(".");
        security_sb_post_mountroot();
diff -uprN linux-2.6.18.1/init/do_mounts_initrd.c 
comma_root/init/do_mounts_initrd.c
--- linux-2.6.18.1/init/do_mounts_initrd.c      2006-10-13 20:34:03.000000000 
-0700
+++ comma_root/init/do_mounts_initrd.c  2006-11-17 15:45:18.000000000 -0800
@@ -113,11 +113,9 @@ int __init initrd_load(void)
                 * mounted in the normal path.
                 */
                if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
-                       sys_unlink("/initrd.image");
                        handle_initrd();
                        return 1;
                }
        }
-       sys_unlink("/initrd.image");
        return 0;
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to