# boot using root filesystem LABEL - without genkernel

## paziu

I am not a big fan of genkernel, and I have struggled with my system every time I made a change to the disk configuration -  SATA, SCSI RAID and dual channel SCSI installed, several disk configurations and different boot order possible, gave me headaches, since the system could not access root after adding or removing one of the HDDs. There is several custom initrd/initramfs guides, overloaded with dependencies such as hotplug. udev, it is exceeding my needs, and becoming unpleasant to maintain after the kernel or package updates...the root device in the guides is often hard-coded - mine is a busybox only initramfs and detects the root dev on fly.

NOTE: if you are currently using genkernel, this post is probably not for you  OR  migrate to a standalone, non-modular kernel first, proceed ONLY if you boot with success

you have to have ALL required hard disk controller drivers BUILT-IN the kernel - this initramfs does not contain ANY modules!

requirements:

1> busybox ( static built - USE="static" )

to do:

1> busybox

```
USE="static" emerge busybox
```

2> create a directory /usr/src/initramfs, create subfolders and copy all the required devs and busybox :

```
mkdir /usr/src/initramfs

cd /usr/src/initramfs

mkdir -p bin lib dev etc mnt/root proc root sbin sys

cp -a /dev/{null,console,tty,sd*,hd*} /usr/src/initramfs/dev

cp -a /bin/busybox /usr/src/initramfs/bin
```

3> use your favorite editor to edit /usr/src/initramfs/init , once done chmod 755 /usr/src/initramfs/init

```
#!/bin/busybox sh

# will drop to shell if mount fails

rescue_shell() {

    echo "Something went wrong. Dropping to the shell."

    busybox --install -s

    exec /bin/sh

    }

# Mount the /proc and /sys filesystems.

mount -t proc none /proc

mount -t sysfs none /sys

# parse /proc/cmdline arguments - LABEL

for arg in $(cat /proc/cmdline); do

   case $arg in

     LABEL=*)

     LABEL="${arg#LABEL=}"

     echo $LABEL

     ;;

   esac

done

# set ROOTDEV

ROOTDEV=`blkid | grep $LABEL | cut -d ":" -f1`

# mount ROOTDEV otherwise shell

mount -o ro $ROOTDEV /mnt/root || rescue_shell

echo "ROOT mounted on $ROOTDEV"

# Clean up

umount /proc

umount /sys

# Boot the thing.

exec switch_root /mnt/root /sbin/init
```

This init script will find "LABEL=xyz" kernel boot argument, which contains the label of your /dev/sdx ( or /dev/hdx) root partition. determine your root filesystem device ( via blkid ) and mount the root filesystem. if root is on LogicalVolume, you will need to add a few LVM tools....

4> example initramfs file/dir structure: ( # find . | sort )

```

.

./bin

./bin/busybox

./dev

./dev/console

./dev/null

./dev/sda

./dev/sda1

./dev/sda2

./dev/sda3

./dev/sdb

./dev/sdb1

./dev/sdb2

./dev/sdb3

./dev/sdc

./dev/sdc1

./dev/sdc2

./dev/sdc3

./dev/sdd

./dev/sdd1

./dev/sdd2

./dev/sdd3

./dev/sde

./dev/sde1

./dev/sde2

./dev/sde3

./dev/tty

./etc

./init

./lib

./mnt

./mnt/root

./proc

./root

./sbin

./sys

```

( if you need more /dev/sd* or /dev/hd* in your initramfs use mknod to add or copy from /dev)

a mknod example: 

a sde4 device is created in the iniramfs/dev tree, to handle 4th partition on sde HDD:

```

mknod -m 660 sde4 b 8 68

```

initramfs dev directory: (/usr/src/initramfs/dev)

```

crw-------  1 root root 5,  1 Oct 31 00:07 console

crw-rw-rw-  1 root root 1,  3 Oct 25 16:08 null

brw-rw----  1 root disk 8,  0 Oct 31 00:23 sda

brw-rw----  1 root disk 8,  1 Oct 31 00:23 sda1

brw-rw----  1 root disk 8,  2 Oct 31 00:23 sda2

brw-rw----  1 root disk 8,  3 Oct 31 00:23 sda3

brw-rw----  1 root disk 8, 16 Oct 31 00:23 sdb

brw-rw----  1 root disk 8, 17 Oct 31 00:23 sdb1

brw-rw----  1 root disk 8, 18 Oct 31 00:23 sdb2

brw-rw----  1 root disk 8, 19 Oct 31 00:02 sdb3

brw-rw----  1 root disk 8, 32 Oct 27 19:49 sdc

brw-rw----  1 root disk 8, 33 Oct 25 16:08 sdc1

brw-rw----  1 root disk 8, 34 Oct 25 16:08 sdc2

brw-rw----  1 root disk 8, 35 Oct 31 00:02 sdc3

brw-rw----  1 root disk 8, 48 Oct 27 19:49 sdd

brw-rw----  1 root disk 8, 49 Oct 25 16:08 sdd1

brw-rw----  1 root disk 8, 50 Oct 25 16:08 sdd2

brw-rw----  1 root disk 8, 51 Oct 31 00:02 sdd3

brw-rw----  1 root disk 8, 64 Oct 30 12:29 sde

brw-rw----  1 root disk 8, 65 Oct 29 22:31 sde1

brw-rw----  1 root disk 8, 66 Oct 31 00:01 sde2

brw-rw----  1 root disk 8, 67 Oct 31 00:03 sde3

brw-rw----  1 root root 8, 68 Oct 31 15:47 sde4  <-----  the new dev

crw-rw-rw-  1 root tty  5,  0 Oct 29 21:24 tty

```

Create the initramfs using the following command - issue the command once in /usr/src/initramfs directory

make sure /boot is mounted....

```

find . -print0 | cpio --null -ov --format=newc | gzip -9 > /boot/labelinitramfs.gz

```

5> example grub.conf - "LABEL=" argument is required, otherwise you finish your boot in the rescue_shell

```

default 0

timeout 30

title Gentoo Linux 2.6.35-r11

root (hd0,0)

kernel /boot/kernel-2.6.35-gentoo-r11 LABEL=gentoo_root

initrd /boot/labelinitramfs.gz

```

as you see, I labeled the ROOT filesystem "gentoo_root" - use e2label to view/set the label on your root dev:

# e2label /dev/(root_device) gentoo_root

6> and this is a final change : /etc/fstab

NOTE: you can test your initamfs WITHOUT changing fstab, once it detects the root fs label, and boots correctly, you can go ahead and make this change

if you are unable to boot, you will be still able to mount root from the initramfs busybox rescue_shell, and modify/tweak the fstab

```

#/dev/sdd1               /boot           ext3   noauto,noatime  1 2

LABEL=gentoo_boot        /boot           ext3   noauto,noatime  1 2

#/dev/sdd2               /              ext3   noatime          0 1

LABEL=gentoo_root        /              ext3   noatime          0 1

/dev/sdd3                 none          swap   sw               0 0

```

if you done, followed this instructions, and able to boot all the way, you can test and add/remove drives from SATA/SCSI/IDE, boot to grub, and the ROOT should be detected on any of the /dev/sdX or /dev/hdX combinations.

Again, if your system has e.g. 5 drives, you have to have /dev/sda(N)......sde(N) for SCSI/SATA or/and /dev/hda(N)....hde(N) for IDE devices

Copy them from /dev or create via mknod

Good Luck!

I also used the following gentoo initramfs guide: ( hardcoded ROOT_DEV )

 *Quote:*   

> 
> 
> http://en.gentoo-wiki.com/wiki/Initramfs
> 
> 

 

- make sure you make a backup of your original grub.conf and fstab

- comment out the original lines, do not overwrite/delete, 

- copy/paste and than make the modifications

better safe than sorry  :Smile: Last edited by paziu on Mon Nov 01, 2010 2:37 pm; edited 2 times in total

----------

## Naib

umm you don't have todo any of that. You don't need an initramfs to mount via LABEL  I have been doing it for years and the only initramfs I have is for a splash

misinformation

----------

## paziu

Well, so looks like I was not doing something right with the LABEL before adding initramfs...

After not being successful, and reading some posts on forums.gentoo and other sites, most/all were saying that some kind of initramfs/initrd is needed for the kernel to "understand" the label -> dev assignment - from what you are saying, such posts should be considered as misleading?

I will try again without initramfs... 

Thanks!

EDIT:

tried again on 2.6.35-r7 : 

oops:

VFS: cannot open root device LABEL="gentoo_root" or unknown-block(2,0)

grub.conf: ..... root=LABEL=gentoo_root .....

fstab: LABEL=gentoo_root     /   .........

and of course, all required adapter modules are built-in

If somebody can confirm mounting by LABEL without initrd/initramfs, using gentoo-sources, I will request to remove this post - Thanks!

----------

## Gusar

 *Naib wrote:*   

> umm you don't have todo any of that. You don't need an initramfs to mount via LABEL  I have been doing it for years and the only initramfs I have is for a splash
> 
> misinformation

 

You can use LABEL in /etc/fstab, but you can't use it on the kernel commandline (in grub or whatever bootloader you're using). To use it on the kernel commandline, you need an initramfs.

----------

## paziu

I agree, this is what I thought, using it only in fstab does not solve the problem of booting off any of available sdX / hdX, withount initramfs/initrd and will end up with OOPS if kernel argument is missing or incorrect....

for most environments I  prefer "root by DEV" rather than "by LABEL", but not in case of a system, that the HDD & HDC configuration and order changes quite often.

Thank you!

ps: you ( or it ) should be able to boot successfully even if "/" in fstab is missing or misconfigured, root=/dev/sdX at the kernel cmdline takes over fstab - as long as the kernel knows where to find "/sbin/init"

 ( unless you mount / Read-Only in initrd - it has to be remounted R/W based on fstab )

 *Quote:*   

> 
> 
> You can use LABEL in /etc/fstab, but you can't use it on the kernel commandline (in grub or whatever bootloader you're using). To use it on the kernel commandline, you need an initramfs.

 

----------

## kingfame_147

Why are you using blkid for that?

There is a build in function (from busybox) to find a filesystem by label or uuid called "findfs".

So you could do something like

```

mount -o ro $(findfs "$type"="$uuid") /mnt/root

```

Here is my initscript. It was written in 5 minutes and I didn't had time to improve it. Feel free to use or correct it :) It works with LABEL and UUID and got a switch for the cmdline called "rescue". Just put "rescue" into the cmdline to drop into a busybox shell to fix something.

```

#!/bin/busybox sh

rs="no"

#sets up the initramfs with /proc, /sys etc.

setup_initramfs() {

    # Mount the /proc and /sys filesystems.

    mount -t proc none /proc

    mount -t sysfs none /sys

    #setup mdev

    echo /sbin/mdev > /proc/sys/kernel/hotplug

    /sbin/mdev -s

}

#search the cmdline for known options

cmdline() {

    for cmd in $(cat /proc/cmdline) ; do

        case $cmd in

            root=*)

                uuidlabel_root $cmd || rescue_shell

                ;;

            rescue)

                rs="yes"

                ;;

        esac

    done

}

#mount root as UUID or LABEL, /dev/sd?? is also working

uuidlabel_root() {

    type=$(echo $1 | cut -d= -f2)

    if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then

        uuid=$(echo $1 | cut -d= -f3)

        mount -o ro $(findfs "$type"="$uuid") /mnt/root

    else

        mount -o ro $(echo $1 | cut -d= -f2) /mnt/root

    fi

}

#clean up and switch to the real root

real_root() {

    # Clean up.

    umount /proc

    umount /sys

    # Boot the real thing.

    exec switch_root /mnt/root /sbin/init

}

#drops into a busybox shell if something went wrong

rescue_shell() {

    echo "Something went wrong. Dropping you to a shell."

    busybox --install -s

    exec /bin/sh

}

#function to call everything what needed

main() {

    setup_initramfs || rescue_shell

    cmdline

    

    if [ $rs == "yes" ] ; then

        rescue_shell

    else

        real_root

    fi

}

main

```

----------

## paziu

Thank you kingfame_147,

blkid is also build in into busybox, but findfs seems to be a "cleaner" way...

Nice!

Thanks!

----------

## kingfame_147

Yeah, I know.

But it's like you said: findfs is the cleaner way, because it is made for exactly that function :)

I used blkid before, too. But then I runned into a bug and read that there is findfs.

----------

## paziu

findfs and blkid are probably are doing almost the same thing... in both cases all "known" adapters need to be scanned for block devices ( takes a few seconfs on 4 HDCs I got ), blkid returns everthing, findfs shows only dev name for the given LABEL or UUID,

in the "findfs" script, the line:

 /sbin/mdev -s 

will not work, since busybox was not "--install -s" so, there is nothing in sbin, unless you add a symlink earlier.... 

 mdev -s    

will do...

I like the idea with mdev, since manually adding of missing block dev files is not needed...

works for me! Thanks!

----------

## kingfame_147

Yeah, I added that symlink because I like to have such sbin tools at /sbin. Just a personal preference.

----------

