lkml.org 
[lkml]   [2000]   [Dec]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] mutliple root devs (take II)
A much cleaner patch prompted after right proper chastisement on the
sloppy patch I sent a few days back. This one is against 2.4-pre11 but so
far as I can tell should be good to go against any of the 2.4 series so
far.

I have not implemented a regex-like syntax as was suggested because 1) you
can still do the same stuff just takes more typing 2) would make for a
fairly large re-ordering of code afterall.

basic idea here is that the kernel will search through a list of root
devices passed to the kernel as arguements before giving up on the rootfs.

ie.

(from lilo:)

linux root=/dev/hda1,/dev/hdc,/dev/hda7

will try each device in order. You can also split these up into separate
root= statements just fine.

please be sure to directly address me with any feedback as I'm not on the
list. (I miss linux-kernel-digest).

t. camp


--snip--
diff --recursive --unified --ignore-all-space linux/Documentation/kernel-parameters.txt linux-2.4.0.11/Documentation/kernel-parameters.txt
--- linux/Documentation/kernel-parameters.txt Tue Sep 5 13:51:14 2000
+++ linux-2.4.0.11/Documentation/kernel-parameters.txt Mon Nov 27 17:25:04 2000
@@ -473,7 +473,11 @@

ro [KNL] Mount root device read-only on boot.

- root= [KNL] root filesystem.
+ root= [KNL] root filesystem, comma separated list of up
+ to eight /dev/ entries will be tried in order
+ presented until kernel suceeds in mounting a
+ filesystem, multiple independant 'root=' entries
+ allowed as well.

rw [KNL] Mount root device read-write on boot.

diff --recursive --unified --ignore-all-space linux/fs/super.c linux-2.4.0.11/fs/super.c
--- linux/fs/super.c Mon Oct 16 12:57:59 2000
+++ linux-2.4.0.11/fs/super.c Wed Nov 29 16:56:00 2000
@@ -18,6 +18,8 @@
* Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
* Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
* Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
+ * Modifications to mount_root for trying a list of root devices.
+ * Tracy Camp <campt@openmars.com> 11/22/00
*/

#include <linux/config.h>
@@ -1470,6 +1472,7 @@
void *handle;
char path[64];
int path_start = -1;
+ int root_device_index = 0;

#ifdef CONFIG_ROOT_NFS
void *data;
@@ -1528,8 +1531,15 @@
}
#endif

- devfs_make_root (root_device_name);
- handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
+ for(root_device_index = 0; root_device_index < number_root_devs; root_device_index++) {
+ printk("VFS: trying root on %s\n",&root_device_name[root_device_index][0]);
+ if(root_device_name[root_device_index][0] != '\0')
+ {
+ ROOT_DEV = name_to_kdev_t(&root_device_name[root_device_index][0]); /* translate */
+ }
+ devfs_make_root (&root_device_name[root_device_index][0]);
+ handle = devfs_find_handle (NULL,
+ &root_device_name[root_device_index][0],
MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
DEVFS_SPECIAL_BLK, 1);
if (handle) /* Sigh: bd*() functions only paper over the cracks */
@@ -1566,10 +1576,10 @@
* and bad superblock on root device.
*/
printk ("VFS: Cannot open root device \"%s\" or %s\n",
- root_device_name, kdevname (ROOT_DEV));
- printk ("Please append a correct \"root=\" boot option\n");
- panic("VFS: Unable to mount root fs on %s",
+ &root_device_name[root_device_index][0], kdevname (ROOT_DEV));
+ printk("VFS: Unable to mount root fs on %s\n",
kdevname(ROOT_DEV));
+ continue;
}

check_disk_change(ROOT_DEV);
@@ -1593,7 +1603,10 @@
put_filesystem(fs_type);
}
read_unlock(&file_systems_lock);
- panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+ printk("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+ } /* end for */
+ printk("VFS: Please append a corrent \"root=\" boot option\n");
+ panic("VFS: Unable to mount any root fs at all");

mount_it:
printk ("VFS: Mounted root (%s filesystem)%s.\n",
@@ -1772,6 +1785,15 @@
} else
path_release(&devfs_nd);
}
+/* this function seems to only be used when after an initrd usage,
+* so the actual value of ROOT_DEV hasn't been determined until mount_root
+* is called, because we try a list of root devices before giving up,
+* this ROOT_DEV global is somewhat misleading now, as its only valid after
+* a call to mount_root because mount_root ignores the ROOT_DEV value
+* except for nfs and ram mount attempts going in, but will realise
+* to not mount RAM again so it should be okay to leave this be.
+* - 11/22/00 <campt@openmars.com>
+*/
ROOT_DEV = new_root_dev;
mount_root();
#if 1
diff --recursive --unified --ignore-all-space linux/include/linux/fs.h linux-2.4.0.11/include/linux/fs.h
--- linux/include/linux/fs.h Wed Nov 29 13:15:25 2000
+++ linux-2.4.0.11/include/linux/fs.h Wed Nov 29 15:38:49 2000
@@ -1229,7 +1229,9 @@
unsigned long generate_cluster(kdev_t, int b[], int);
unsigned long generate_cluster_swab32(kdev_t, int b[], int);
extern kdev_t ROOT_DEV;
-extern char root_device_name[];
+extern char root_device_name[8][64];
+extern int number_root_devs;
+extern kdev_t name_to_kdev_t(char *); /* in init/main.c */


extern void show_buffers(void);
diff --recursive --unified --ignore-all-space linux/init/main.c linux-2.4.0.11/init/main.c
--- linux/init/main.c Fri Nov 17 16:45:57 2000
+++ linux-2.4.0.11/init/main.c Wed Nov 29 15:39:27 2000
@@ -130,7 +130,8 @@

int root_mountflags = MS_RDONLY;
char *execute_command;
-char root_device_name[64];
+char root_device_name[8][64];
+int number_root_devs = 0;


static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
@@ -261,10 +262,11 @@
kdev_t __init name_to_kdev_t(char *line)
{
int base = 0;
+ struct dev_name_struct *dev = root_dev_names;

if (strncmp(line,"/dev/",5) == 0) {
- struct dev_name_struct *dev = root_dev_names;
line += 5;
+ }
do {
int len = strlen(dev->name);
if (strncmp(line,dev->name,len) == 0) {
@@ -274,7 +276,6 @@
}
dev++;
} while (dev->name);
- }
return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
}

@@ -283,15 +284,40 @@
int i;
char ch;

- ROOT_DEV = name_to_kdev_t(line);
- memset (root_device_name, 0, sizeof root_device_name);
+/* number_root_devs is initially 0 and not touched except for
+incrementing, so this function should be re-callable with the
+desired results */
if (strncmp (line, "/dev/", 5) == 0) line += 5;
- for (i = 0; i < sizeof root_device_name - 1; ++i)
- {
+ memset (root_device_name[number_root_devs], 0, sizeof root_device_name[number_root_devs]);
+ for (i = 0; i < sizeof root_device_name[number_root_devs] - 1; ++i) {
+ ch = line[i];
+ if ( ch == ',') {
+ if(number_root_devs == 0) {
+ ROOT_DEV = name_to_kdev_t(&root_device_name[number_root_devs][0]);
+ }
+ number_root_devs++;
+ if(number_root_devs >= 8) {
+ break;
+ }
+ i++;
+ line += i;
+ i = 0;
+ if (strncmp (line, "/dev/", 5) == 0) {
+ line += 5;
+ }
ch = line[i];
- if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
- root_device_name[i] = ch;
+ memset (root_device_name[number_root_devs], 0, sizeof root_device_name[number_root_devs]);
+ }
+ if ( isspace (ch) || (ch == '\0') ) {
+ if(number_root_devs == 0) {
+ ROOT_DEV = name_to_kdev_t(&root_device_name[number_root_devs][0]);
+ }
+ number_root_devs++;
+ break;
+ }
+ root_device_name[number_root_devs][i] = ch;
}
+printk("root_dev_setup number_root_devs: %d\n",number_root_devs);
return 1;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 12:49    [W:0.076 / U:0.744 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site