Messages in this thread Patch in this message | | | Date | Wed, 04 Aug 1999 10:17:06 +0200 | From | David Balazic <> | Subject | [PATCH] Select root-fs by UUID or label |
| |
Here is a patch against kernel 2.2.5-22 ( REDHAT ) , works with 2.2.10 too, that allows selecting the root file-system by it's volume label or UUID. Usage:
Pass the kernel the root parameter, for UUID : root=UUID:4343554-545-5454-54554 for label: root=L:linux1
the old syntax ( root=/dev/hda3 or root=306 ) still works.
A note about lilo: use the option append="root=L:linux2root" instead of root=L:xxxx in lilo.conf , because lilo tries to convert the entry into a hexadecimal major-minor pair. Other boot loaders may have similar issues.
It is a "works for me" quality code, so beware :-)
Since Outlook probably mangled the tabs , there is a good version of the patch at : http://rcum.uni-mb.si/~uel003r2a/UUID.PATCH
Oh, and please CC me any replies ( to david.balazic@uni-mb.si ) since I am not subscribed to linux-kernel.
diff -u -r linux-2.2.5-22-redhat/Documentation/Configure.help linux/Documentation/Configure.help --- linux-2.2.5-22-redhat/Documentation/Configure.help Wed Jun 2 14:36:15 1999 +++ linux/Documentation/Configure.help Thu Jul 29 17:08:59 1999 @@ -6826,6 +6826,25 @@ compiled as a module, and so this could be dangerous. Most everyone wants to say Y here.
+Select root file-system by UUID or volume label +CONFIG_ROOT_FS_LABEL + If you say Y, you will be able to select the root file-system + by it's UUID or volume label with the root= kernel parameter. + Examples : + root=UUID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + root=L:linux-root + + You can still use the old root=/dev/hda1 and root=307 forms. + + Currently, it works only with the ext2 filesystem. + + If you are using LILO you MUST use the option + append="root=L:xxx" instead of just root=L:xxx + in the lilo.conf file. LILO tries to parse the boot= + option itself, while it just passes the append string + to the kernel. Loadlin and other loader may have similar problems. + If you say Y, you will be able to select the root file-system + ISO 9660 CDROM filesystem support CONFIG_ISO9660_FS This is the standard filesystem used on CDROMs. It was previously diff -u -r linux-2.2.5-22-redhat/fs/Config.in linux/fs/Config.in --- linux-2.2.5-22-redhat/fs/Config.in Mon Mar 8 00:25:23 1999 +++ linux/fs/Config.in Thu Jul 29 15:53:05 1999 @@ -49,6 +49,9 @@ fi tristate 'ROM filesystem support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS +if [ "$CONFIG_EXT2_FS" = "y" ]; then + bool 'Select root file-system by UUID or volume label' CONFIG_ROOT_FS_LABEL +fi tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS tristate 'UFS filesystem support' CONFIG_UFS_FS if [ "$CONFIG_UFS_FS" != "n" ]; then diff -u -r linux-2.2.5-22-redhat/fs/super.c linux/fs/super.c --- linux-2.2.5-22-redhat/fs/super.c Wed Jun 2 14:36:14 1999 +++ linux/fs/super.c Thu Jul 29 16:14:34 1999 @@ -15,6 +15,9 @@ * * Added kerneld support: Jacques Gelinas and Bjorn Ekwall * Added change_root: Werner Almesberger & Hans Lermen, Feb '96 + * + * Added support for selecting the root-fs by UUID or label + * David Balazic <1stein@writeme.com>, Jul 1999 */
#include <linux/config.h> @@ -36,6 +39,11 @@ #include <linux/kmod.h> #endif
+#ifdef CONFIG_ROOT_FS_LABEL +#include <linux/genhd.h> +#include <linux/ext2_fs.h> +#endif + /* * We use a semaphore to synchronize all mount/umount * activity - imagine the mess if we have a race between @@ -1114,6 +1122,52 @@ goto dput_and_out; }
+#ifdef CONFIG_ROOT_FS_LABEL +/* + * check_dev(int major,int minor) + * check if the partition has the right label or UUID. + * Based on code from util-linux-2.9s/mount/mount_by_label.c + * ( matching the label/UUID ) and /usr/src/linux/fs/ext2/super.c + * ( loading the blocks ) + */ +static int __init check_dev(int major, int minor) +{ + extern char root_dev_label[16]; + extern int root_dev_type; + int blocksize; + unsigned long logic_sb_block = 1; + unsigned long offset = 0; + kdev_t dev; + struct buffer_head *bh; + struct ext2_super_block *e2sb; + int result = 0; + + dev = to_kdev_t((major << 8) | (minor & 0xff)); /* or maybe MKDEV(major,minor) ? */ + + if ((blocksize = get_hardblocksize(dev)) == 0) + blocksize = BLOCK_SIZE; + + if (blocksize != BLOCK_SIZE) { + logic_sb_block = (1 * BLOCK_SIZE) / blocksize; + offset = (1 * BLOCK_SIZE) % blocksize; + } + if (!(bh = bread(dev, logic_sb_block, blocksize))) + return 0; + + e2sb = (struct ext2_super_block *) (((char *) bh->b_data) + offset); + + if (le16_to_cpu(e2sb->s_magic) == EXT2_SUPER_MAGIC) { + if (strncmp((root_dev_type == 1) ? (char *) e2sb->s_uuid : e2sb->s_volume_name, + root_dev_label, 16)) + result = 0; + else + result = 1; + } + brelse(bh); + return result; +} +#endif + void __init mount_root(void) { struct file_system_type * fs_type; @@ -1123,6 +1177,29 @@ struct file filp; int retval;
+#ifdef CONFIG_ROOT_FS_LABEL + extern int root_dev_type; + + if (root_dev_type != 0) { + struct gendisk *p; + int n; + + if (root_dev_type == 3) + panic("Badly formatted UUID was supplied as kernel parameter root"); + + for (p = gendisk_head; p; p = p->next) + for (n = 0; n < (p->nr_real << p->minor_shift); n++) + if (p->part[n].nr_sects > 8) /* avoid empty , too small and extended partitions */ + if (check_dev(p->major, n)) { + ROOT_DEV = to_kdev_t((p->major << 8) | (n & 0xff)); + goto root_dev_found; + } +/* panic("VFS: didn't found the root fs based on UUID or label"); */ + printk("VFS: didn't found the root fs based on UUID or label, trying old method\n"); + } + root_dev_found: +#endif + #ifdef CONFIG_ROOT_NFS if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { ROOT_DEV = 0; diff -u -r linux-2.2.5-22-redhat/init/main.c linux/init/main.c --- linux-2.2.5-22-redhat/init/main.c Wed Jun 2 14:36:14 1999 +++ linux/init/main.c Thu Jul 29 16:20:01 1999 @@ -7,6 +7,9 @@ * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96 * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96 * Simplified starting of init: Michael A. Griffith <grif@acm.org> + * + * Added support for selecting the root file system by ext2 label or UUID : + * David Balazic <1stein@writeme.com> Jul 1999 */
#define __KERNEL_SYSCALLS__ @@ -539,8 +542,70 @@ return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16)); }
+#ifdef CONFIG_ROOT_FS_LABEL +char root_dev_label[16]; +int root_dev_type; /* 0 - normal /dev/xxx or 302 , + 1 - UUID, 2 - label , 3 - bad UUID */ + +/* taken from util-linux-2.9s/mount/mount_by_label.c */ +static u_char __init fromhex(char c) +{ + if (isdigit(c)) + return (c - '0'); + else if (islower(c)) + return (c - 'a' + 10); + else + return (c - 'A' + 10); +} + +static void __init parse_uuid(const char *s) +{ + int i; + + if (strlen(s) != 36 || + s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') + goto bad_uuid; + for (i = 0; i < 16; i++) { + if (*s == '-') + s++; + if (!isxdigit(s[0]) || !isxdigit(s[1])) + goto bad_uuid; + root_dev_label[i] = ((fromhex(s[0]) << 4) | fromhex(s[1])); + s += 2; + } + return; + bad_uuid: + root_dev_type = 3; + +/* panic("Bad UUID was supplied for root-fs\n"); */ + + /* Unfortunately , panic() doesn't work here. + * The machine is stopped , but there is no output, + * except "... Decompressing kernel ..." + * so I delay it until mount_root time + */ +} +#endif + static void __init root_dev_setup(char *line, int *num) { +#ifdef CONFIG_ROOT_FS_LABEL + if (strncmp(line, "L:", 2) == 0) { + line += 2; + strncpy(root_dev_label, line, 16); + root_dev_type = 2; + /* maybe a warning would be appropriate + * if the supplied label is longer than 16 chars, + * now it is silently truncated */ + return; + } else if (strncmp(line, "UUID:", 5) == 0) { + line += 5; + root_dev_type = 1; + parse_uuid(line); + return; + } + root_dev_type = 0; +#endif ROOT_DEV = name_to_kdev_t(line); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |