In linux, hard drives are referred to as devices and are represented as pseudo files in /dev. For example, the first partition of the second lowest numbered SCSI drive is /dev/sdb1. If the drive referred to as /dev/sda is removed, then the remaining partition is automatically renamed /dev/sda1 at reboot, which can potentially cause your system not to boot.

Note: if you are using LVM, then this post isn't relevant as LVM already supports persistent naming.

Inversely, imagine you've got a system with internal SAS disks that has been working fine, with the root filesystem on /dev/sda and some other key directory (like /usr/) on /dev/sdb.  After a while, you decide to add some additional storage via a Fiber Channel card and all of a sudden the system won't boot correctly because the RAID array on your fibre channel disks has become /dev/sda.

However, some people don't seem to know that this can be easily resolved by using one of the schemes for persistent naming.  From man fstab:

Instead of giving the device explicitly, one may indicate the
 (ext2 or xfs) filesystem that is to be mounted by its UUID or
 volume label (cf. e2label(8) or xfs_admin(8)), writing
 LABEL=<label> or UUID=<uuid>, e.g., LABEL=Boot or UUID=3ede-813...
 This will make the system more robust: adding or removing a SCSI
 disk changes the disk device name but not the filesystem volume label.

Persistent naming

There are two main methods of addressing filesystems in a persistent fashion; by-uuid or bl-label.

  • UUID is a mechanism to give each filesystem a unique identifier. All Linux filesystems (including swap) support UUID.  And although, FAT and NTFS filesystems technically don't, they will still be presented with a unique identifier.  The downside is that they're not very readable (eg. 63c9c012-d93d-4953-962a-66f8130238af).
  • Almost all filesystems types can have a label, including ext2, ext3, xfs, btrfs and swap filesystems.  FAT file
    systems don't have any mechanism to support disk labels, so you should use the udev by-id device specification instead.  Labels are the preferred method, but can suffer from name collisions if you're not sensible about the labels you assign.

On boot, udev reads the available filesystem labels and configures useful symlinks under /dev/disk:

[[email protected] ~]# ls -lR /dev/disk/by-uuid
lrwxrwxrwx 1 root root 10 Apr 26  2010 63c9c012-d93d-4953-962a-66f8130238af > ../../sda1
[[email protected] ~]# ls -lR /dev/disk/by-label
lrwxrwxrwx 1 root root 10 Apr 26  2010 boot -> ../../sda1

You can also use the blkid command to query block device attributes, including UUID and labels:

[[email protected] ~]# blkid
/dev/mapper/VolGroup00-LogVol01: TYPE="swap"
/dev/mapper/VolGroup00-LogVol00: UUID="b990560a-1d49-4751-afdb-7f3bd070d140" TYPE="ext3"
/dev/sda1: LABEL="/boot" UUID="63c9c012-d93d-4953-962a-66f8130238af" TYPE="ext3"
/dev/hda: LABEL="CentOS_5.3_Final" TYPE="iso9660"
/dev/VolGroup00/LogVol00: UUID="b990560a-1d49-4751-afdb-7f3bd070d140" TYPE="ext3"
/dev/VolGroup00/LogVol01: TYPE="swap"

Setting Disk Labels

How to set or change a disk label depends on the filesystem.  Below are some common examples:

EXT2/EXT3: e2label /dev/XXX <label>

ReiserFS: reiserfstune -l <label> /dev/XXX

JFS: jfs_tune -L <label> /dev/XXX

XFS: xfs_admin -L <label> /dev/XXX

Btrfs: btrfs filesystem label <device> <newlabel>

Swap: mkswap -L SWAP0 /dev/XXX

Using Persistent Naming

There are two ways to use the above persistent naming schemes.  Firstly, you could simple reference the device by the symlink in /dev/disk/by-uuid/XXX or /dev/disk/by-label/XXX as shown above, or, more directly as in the examples below by prefixing with either LABEL=XXX or UUID=XXX.

Example of /etc/fstab with disk labels:

LABEL=ROOT          /         ext3    defaults      - 1
LABEL=BOOT          /boot     ext3    defaults      - 2
LABEL=SWAP          swap      swap    defaults      0 0
LABEL=HOME          /home     ext3    nosuid,auto   - 2

Example of /boot/grub/grub.conf with disk labels:

title CentOS  root (hd0,0)
kernel (hd0,0)/vmlinuz ro root=LABEL=ROOT rhgb quiet
initrd (hd0,0)/initrd.img