lkml.org 
[lkml]   [1999]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] UUID and label support for root file-system
Date
OK , here is a patch which makes it possible to specify the root FS by its
UUID or
volume label. It works with ext2 only for obvious reasons.

Usage :
pass the root= parameter to the kernel

root=UUID:43534543-6565-656-6565564564 for UUIDs or
root=L:myLinuxRoot for labels

root=/dev/hda1 and root=305 work too, as before.

When using lilo use the append="root=what-ever" instead of just root=xxx.

The patch is agains kernel 2.2.5 , but applies to 2.2.10 too.

Send (or CC) any comments to me at david.balazic@uni-mb.si
( I'm not subscribed to linux-kernel )

The patch ( also avaliable at http://www.uni-mb.si/~uel003r2a/uuid.patch ,
this has the tabs mangled) :

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/

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