How to mount disks by label
The order in which USB devices are initialised at boot time is somewhat random. This is problematic in the case of disks as the SCSI drive identifiers (sda, sdb etc) normally used to refer to them in /etc/fstab are allocated sequentially. One way to avoid this problem is to give labels to each of the filesystems and to refer to them using those labels in /etc/fstab.
If your slug always seems to power on with its drives in the same order, you may just be lucky. Maybe next week you'll add a new peripheral and it will all change. In my case I replaced a failed flash drive with a new one and subsequently the two drives swapped around on each boot.
This page is written with Debian / NSLU2 in mind. It is probably somewhat applicable to other NSLU2 software distributions. Users of other distributions, please add comments.
The basic procedure is as follows:
Adding labels to filesystems
Note that the labels apply to partitions, not to disks.
For ext2 and ext3 filesystems you can use the tune2fs program to add labels:
# tune2fs -L root /dev/sda1
Where -L specifies the name you'll be assigning the drive (in this case, "root")
For your swap partition you can set a label using mkswap, but you need to swapoff first:
# swapoff -a # mkswap -L swap /dev/sda2 # swapon -a
Choose labels that use characters that are legal in filenames. In particular I suggest not using the "/" character in labels since it breaks the /dev/disk stuff described below. This is an interesting point because I believe that RedHat may have standardised on using "/" as the label on the root filesystem; this works for them because they use an alternative "LABEL=" syntax instead of /dev/disk.
OpenWrt uses the same "LABEL=" syntax as RedHat. So the "/etc/fstab" entries will differ from the Debian entries below. NOTE: I haven't tested the 'root' label, as my boot device is connected directly to the slug and does not change disk ID.
At this point you should reboot, as the kernel will not be fully aware of the labels until the affected filesystems are remounted.
Have a look at /dev/disk:
# tree /dev/disk /dev/disk |-- by-id | |-- usb-JetFlash_TS1GJFV30_DZPCOJC7 -> ../../sdb | |-- usb-JetFlash_TS1GJFV30_DZPCOJC7-part1 -> ../../sdb1 | |-- usb-JetFlash_TS1GJFV30_DZPCOJC7-part2 -> ../../sdb2 | |-- usb-USB_2.0_Flash_Disk_a86144e24194b3 -> ../../sda | `-- usb-USB_2.0_Flash_Disk_a86144e24194b3-part1 -> ../../sda1 |-- by-label | |-- data -> ../../sda1 | |-- root -> ../../sdb1 | `-- swap -> ../../sdb2 |-- by-path | |-- pci-0000:00:01.2-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdb | |-- pci-0000:00:01.2-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdb1 | |-- pci-0000:00:01.2-usb-0:1:1.0-scsi-0:0:0:0-part2 -> ../../sdb2 | |-- pci-0000:00:01.2-usb-0:2.5:1.0-scsi-0:0:0:0 -> ../../sda | `-- pci-0000:00:01.2-usb-0:2.5:1.0-scsi-0:0:0:0-part1 -> ../../sda1 `-- by-uuid |-- 71b2f940-7e96-4e4f-be18-d712073780b8 -> ../../sdb2 |-- 72ff7f86-243d-4e8f-91cd-40540a60cc1c -> ../../sdb1 `-- 950b2fb6-9a1e-4bce-85a7-bb796a96a061 -> ../../sda1
I believe that these symlinks are all created by udev. You should be able to see the labels that you've just added under /dev/disk/by-label. If you prefer cryptic UUIDs to human-readable labels for some reason you can use the links in /dev/by-uuid. The /dev/by-path links may provide a way to refer to a disk by the hub port that it is connected to, if that is useful to you.
You can now edit /etc/fstab to refer to partitions using their labels instead of the hard-coded /dev/sd names. Mine now looks like this:
proc /proc proc defaults 0 0 /dev/disk/by-label/root / ext3 noatime 1 1 /dev/disk/by-label/swap none swap sw 0 0 /dev/disk/by-label/data /data ext3 noatime 0 0
Or for OpenSlug: (You may have to label the partitions on another system)
proc /proc proc defaults 0 0 LABEL=root / ext3 noatime 1 1 LABEL=swap none swap sw 0 0 LABEL=data /data ext3 noatime 0 0
NOTE: The 'root' entry is untested as stated in the previous note
I suggest checking to see if you have any other files in /etc that use /dev/sd. I didn't find any.
# grep -R 'sd[ab]' /etc
Kernel command line
The kernel doesn't look in /etc/fstab to find the root partition, because /etc/fstab isn't mounted at that time. Instead, the root partition is specified on the kernel command line using the root= parameter; if nothing is specified a default is used.
For Debian / NSLU2, changing the kernel command line is described on ChangeKernelCommandLine. Currently it's a bit complicated. You need to add a parameter something like:
Root filesystem bug
Note: the below section is no longer needed for Debian Lenny 5.0.4 (bug solved); you can just use the APEX tool (
At the time of writing the Debian / NSLU2 distribution has a bug which will cause the root disk that you specify on the kernel command line to be ignored. The problem is inside the initramfs. You can work around this by setting the root device in a new /etc/initramfs-tools/conf.d file and recreating the initramfs. The kernel command line root parameter will still be ignored.
If you want to fix it so that the kernel command line parameter is not ignored, or if you use a custom initramfs or for some other reason can not use update-initramfs, here is an outline of how to fix the bug properly. For more details of how to manage initramfs files, have a look at BuildImage. You probably need to do most of this as root as otherwise the cpio archive that you create will have the wrong ownership information on the files.