public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* kernel cmdline: root=/dev/sdb1,/dev/sda1 "fallback"?
@ 2007-01-17 12:58 Tomasz Chmielewski
  2007-01-17 13:37 ` Jan Engelhardt
  2007-01-17 13:37 ` Alon Bar-Lev
  0 siblings, 2 replies; 16+ messages in thread
From: Tomasz Chmielewski @ 2007-01-17 12:58 UTC (permalink / raw)
  To: linux-kernel

I have a Linux (ARM) device that normally starts from /dev/sda1.

It is configured to do so via a cmdline in a RedBoot bootloader:

root=/dev/sda1


The device is pretty small and has no keyboard, video card etc., so if 
it ever happens to break (can be a disk failure, but also operator who 
messed with startup scripts), it has to be opened (warranty!).


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


/dev/sdb1 - USB-stick which can boot the device
/dev/sda1 - HDD which normally starts the device


It would mean, that kernel tries to boot the OS from /dev/sdb1, and if 
there isn't such a device, it tries to boot the OS from /dev/sda1.


In our case, /dev/sdb1 would be an external USB-stick capable to boot 
the device (in that case, we'd have to add rootdelay= option, too).
One would connect it only if he/she wants to service the device.

If /dev/sdb1 is not found by the kernel, the boot would start 
("fallback") from /dev/sda1.


Does this make sense?


As I understand correctly, the needed change would have to be done in 
init/do_mounts.c, around "static int __init do_mount_root" and "void 
__init mount_block_root"? Any clues on that?


-- 
Tomasz Chmielewski
http://wpkg.org



^ permalink raw reply	[flat|nested] 16+ messages in thread
* Re: kernel cmdline: root=/dev/sdb1,/dev/sda1 "fallback"?
@ 2007-01-18 10:50 Al Borchers
  2007-01-18 14:21 ` Tomasz Chmielewski
  0 siblings, 1 reply; 16+ messages in thread
From: Al Borchers @ 2007-01-18 10:50 UTC (permalink / raw)
  To: linux-kernel



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;
 }

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2007-01-19  4:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-17 12:58 kernel cmdline: root=/dev/sdb1,/dev/sda1 "fallback"? Tomasz Chmielewski
2007-01-17 13:37 ` Jan Engelhardt
2007-01-17 14:09   ` Tomasz Chmielewski
2007-01-17 20:33     ` H. Peter Anvin
2007-01-18 10:33       ` Tomasz Chmielewski
2007-01-18 10:47         ` H. Peter Anvin
2007-01-18 11:48           ` Tomasz Chmielewski
2007-01-18 18:48             ` H. Peter Anvin
2007-01-17 13:37 ` Alon Bar-Lev
2007-01-17 13:56   ` Tomasz Chmielewski
2007-01-17 14:06     ` Alon Bar-Lev
2007-01-17 14:12       ` Jan Engelhardt
  -- strict thread matches above, loose matches on Subject: below --
2007-01-18 10:50 Al Borchers
2007-01-18 14:21 ` Tomasz Chmielewski
2007-01-18 20:33   ` H. Peter Anvin
2007-01-19  4:12   ` Al Borchers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox