Persistent block device naming (简体中文)
本文讲述如何为你的块设备提供持久化命名。udev的导入使之成为可能,也使之优于基于总线的命名法。如果你的机器上有不止一个 SATA, SCSI 或 IDE 磁盘控制器,那么它们所对应的设备节点将会依随机次序添加。这样就可能导致每次引导时设备的名字如 /dev/sda
与 /dev/sdb
互换了,最终导致系统不可引导、kernel panic、或者设备不可见。持久化命名法可以解决这些问题。
Contents
持久化命名的方法
有四种持久化命名方案:by-label、by-uuid、by-id 和 by-path。对于那些使用GUID 分区表(GPT)的磁盘,还有额外的两种方案,by-partlabel 和 by-partuuid。你也可以使用 Udev 静态设备名方案。
下面讲解各种命名方案及其用法。
lsblk -f
命令用于以图示方式查看第一种方案:
$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT sda ├─sda1 vfat CBB6-24F2 /boot ├─sda2 ext4 SYSTEM 0a3407de-014b-458b-b5c1-848e92a327a3 / ├─sda3 ext4 DATA b411dc99-f0a0-4c87-9e05-184977be8539 /home └─sda4 swap f9fe0b69-a280-415d-a03a-a32752370dee [SWAP]
对于 GPT 分区表,应改用 blkid
命令。字母便于脚本使用但可读性降低。
$ blkid
/dev/sda1: UUID="CBB6-24F2" TYPE="vfat" PARTLABEL="EFI SYSTEM PARTITION" PARTUUID="d0d0d110-0a71-4ed6-936a-304969ea36af" /dev/sda2: LABEL="SYSTEM" UUID="0a3407de-014b-458b-b5c1-848e92a327a3" TYPE="ext4" PARTLABEL="GNU/LINUX" PARTUUID="98a81274-10f7-40db-872a-03df048df366" /dev/sda3: LABEL="DATA" UUID="b411dc99-f0a0-4c87-9e05-184977be8539" TYPE="ext4" PARTLABEL="HOME" PARTUUID="7280201c-fc5d-40f2-a9b2-466611d3d49e" /dev/sda4: UUID="f9fe0b69-a280-415d-a03a-a32752370dee" TYPE="swap" PARTLABEL="SWAP" PARTUUID="039b6c1c-7553-4455-9537-1befbc9fbc5b"
by-label
几乎每一个文件系统都可以有一个标签。所有有标签的分区都在 /dev/disk/by-label
目录中列出。这个目录是动态地创建和销毁的,视有无带标签的分区而定。
$ ls -l /dev/disk/by-label
total 0 lrwxrwxrwx 1 root root 10 May 27 23:31 DATA -> ../../sda3 lrwxrwxrwx 1 root root 10 May 27 23:31 SYSTEM -> ../../sda2
The labels of your filesystems can be changed. Following are some methods for changing labels on common filesystems:
- swap
-
swaplabel -L <label> /dev/XXX
using util-linux - ext2/3/4
-
e2label /dev/XXX <label>
using e2fsprogs - btrfs
-
btrfs filesystem label /dev/XXX <label>
using btrfs-progs - reiserfs
-
reiserfstune -l <label> /dev/XXX
using reiserfsprogs - jfs
-
jfs_tune -L <label> /dev/XXX
using jfsutils - xfs
-
xfs_admin -L <label> /dev/XXX
using xfsprogs - fat/vfat
-
dosfslabel /dev/XXX <label>
using dosfstools - fat/vfat
-
mlabel -i /dev/XXX ::<label>
using mtools - ntfs
-
ntfslabel /dev/XXX <label>
using ntfs-3g
by-uuid
UUID is a mechanism to give each filesystem a unique identifier. These identifiers are generated by filesystem utilities (e.g. mkfs.*
) when the partition gets formatted and are designed so that collisions are unlikely. All GNU/Linux filesystems (including swap and LUKS headers of raw encrypted devices) support UUID. FAT and NTFS filesystems (fat and windows labels above) do not support UUID, but are still listed in /dev/disk/by-uuid
with a shorter UID (unique identifier):
$ ls -l /dev/disk/by-uuid/
total 0 lrwxrwxrwx 1 root root 10 May 27 23:31 0a3407de-014b-458b-b5c1-848e92a327a3 -> ../../sda2 lrwxrwxrwx 1 root root 10 May 27 23:31 b411dc99-f0a0-4c87-9e05-184977be8539 -> ../../sda3 lrwxrwxrwx 1 root root 10 May 27 23:31 CBB6-24F2 -> ../../sda1 lrwxrwxrwx 1 root root 10 May 27 23:31 f9fe0b69-a280-415d-a03a-a32752370dee -> ../../sda4
The advantage of using the UUID method is that it is much less likely that name collisions occur than with labels. Further, it is generated automatically on creation of the filesystem. It will, for example, stay unique even if the device is plugged into another system (which may perhaps have a device with the same label).
The disadvantage is that UUIDs make long code lines hard to read and break formatting in many configuration files (e.g. fstab or crypttab). Also every time a partition is resized or reformatted a new UUID is generated and configs have to get adjusted (manually).
by-id and by-path
by-id
creates a unique name depending on the hardware serial number, by-path
depending on the shortest physical path (according to sysfs). Both contain strings to indicate which subsystem they belong to (i.e. -ide-
for by-path
, and -ata-
for by-id
) and thus are not suitable for solving the problems mentioned in the beginning of this article. They will not be discussed any further here.
by-partlabel
Partition labels can be defined in the header of the partition entry on GPT disks.
See also Wikipedia:GUID_Partition_Table#Partition_entries.
This method is very similar to the filesystem labels, excepted that the dynamic directory is /dev/disk/by-partlabel
.
ls -l /dev/disk/by-partlabel/
total 0 lrwxrwxrwx 1 root root 10 May 27 23:31 EFI\x20SYSTEM\x20PARTITION -> ../../sda1 lrwxrwxrwx 1 root root 10 May 27 23:31 GNU\x2fLINUX -> ../../sda2 lrwxrwxrwx 1 root root 10 May 27 23:31 HOME -> ../../sda3 lrwxrwxrwx 1 root root 10 May 27 23:31 SWAP -> ../../sda4
by-partuuid
Like GPT partition labels, GPT partition UUID are defined in the partition entry on GPT disks.
See also Wikipedia:GUID_Partition_Table#Partition_entries.
The dynamic directory is similar to other methods and, like UUID filesystems, using UUIDs is prefered over labels.
ls -l /dev/disk/by-partuuid/
total 0 lrwxrwxrwx 1 root root 10 May 27 23:31 039b6c1c-7553-4455-9537-1befbc9fbc5b -> ../../sda4 lrwxrwxrwx 1 root root 10 May 27 23:31 7280201c-fc5d-40f2-a9b2-466611d3d49e -> ../../sda3 lrwxrwxrwx 1 root root 10 May 27 23:31 98a81274-10f7-40db-872a-03df048df366 -> ../../sda2 lrwxrwxrwx 1 root root 10 May 27 23:31 d0d0d110-0a71-4ed6-936a-304969ea36af -> ../../sda1
使用 Udev 静态设备名
See Udev#Setting static device names.
使用持久化的命名
There are various applications that can be configured using persistent naming. Following are some examples of how to configure them.
fstab
See the main article: fstab#UUIDs
引导管理器
To use persistent names in your boot manager, the following prerequisites must be met:
- You are using a mkinitcpio initial RAM disk image
- You have udev enabled in
/etc/mkinitcpio.conf
In the above example, /dev/sda1
is the root partition. In the GRUB grub.cfg
file, the linux line looks like this:
linux /boot/vmlinuz-linux root=/dev/sda1 rw quiet
Depending on which naming scheme you would prefer, change it to one of the following:
linux /boot/vmlinuz-linux root=/dev/disk/by-label/root_myhost rw quiet
or:
linux /boot/vmlinuz-linux root=UUID=2d781b26-0285-421a-b9d0-d4a0d3b55680 rw quiet
If you are using LILO, then do not try this with the root=...
configuration option; it will not work. Use append="root=..."
or addappend="root=..."
instead. Read the LILO man page for more information on append
and addappend
.
There is an alternative way to use the label embedded in the filesystem. For example if (as above) the filesystem in /dev/sda1
is labeled root_myhost
, you would give this line to GRUB:
linux /boot/vmlinuz-linux root=LABEL=root_myhost rw quiet