塊設備持久化命名

出自 Arch Linux 中文维基

本文講述如何為你的塊設備提供持久化命名。udev的導入使之成為可能,也使之優於基於總線的命名法。如果你的機器上有不止一個 SATA, SCSI 或 IDE 磁盤控制器,那麼它們所對應的設備節點將會依隨機次序添加。這樣就可能導致每次引導時設備的名字如 /dev/sda/dev/sdb 互換了,最終導致系統不可引導、kernel panic、或者設備不可見。持久化命名法可以解決這些問題。

注意:
  • 持久設備名有一些超出本文範圍的限制,比如雖然 mkinitcpio 支持某個方法,但 systemd 會對支持的設備名添加額外的限制(例如 FS#42884)。
  • 本文與 LVM 邏輯卷無關,因為 /dev/VolumeGroupName/LogicalVolumeName 設備路徑是持久化的。

持久化命名的方法[編輯 | 編輯原始碼]

有四種持久化命名方案:通過標籤通過 uuid通過 id 和 通過路徑。對於那些使用GUID 分區表(GPT)的磁盤,還有額外的兩種方案,通過分區標籤通過分區 uuid。你也可以使用 Udev 靜態設備名方案。

/dev/disk/ 中的文件夾是動態創建和銷毀的,這取決於其中是否有設備。

注意: 請注意磁盤克隆會創建兩個有着相同名字的不同磁盤。

下面講解各種命名方案及其用法。

lsblk 命令用於以圖示方式查看第一種方案:

$ lsblk -f
	
NAME        FSTYPE LABEL      UUID                                 MOUNTPOINT
sda                                                        
├─sda1      vfat              CBB6-24F2                            /boot
├─sda2      ext4   Arch Linux 0a3407de-014b-458b-b5c1-848e92a327a3 /
├─sda3      ext4   Data       b411dc99-f0a0-4c87-9e05-184977be8539 /home
└─sda4      swap              f9fe0b69-a280-415d-a03a-a32752370dee [SWAP]
mmcblk0
└─mmcblk0p1 vfat              F4CA-5D75

GUID 分區表的分區應改用 blkid 命令,這個命令更方便腳本使用但可讀性低。

# blkid
/dev/sda1: UUID="CBB6-24F2" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="d0d0d110-0a71-4ed6-936a-304969ea36af"  
/dev/sda2: LABEL="Arch Linux" 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"
/dev/mmcblk0: PTUUID="0003e1e5" PTTYPE="dos"
/dev/mmcblk0p1: UUID="F4CA-5D75" TYPE="vfat" PARTUUID="0003e1e5-01"

通過標籤[編輯 | 編輯原始碼]

幾乎每一種文件系統都可以有一個標籤。所有有標籤的卷都在 /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 Arch\x20Linux -> ../../sda2

大多數文件系統支持在創建文件系統時設置標籤,請見相關的 mkfs.* 工具的 man 手冊頁面。對於一些也可以修改標籤的文件系統。下面列出了一些常見文件系統修改標籤的方式:

swap
swaplabel -L "new label" /dev/XXX 使用 util-linux
ext2/3/4
e2label /dev/XXX "new label" 使用 e2fsprogs
btrfs
btrfs filesystem label /dev/XXX "new label" 使用 btrfs-progs
reiserfs
reiserfstune -l "new label" /dev/XXX 使用 reiserfsprogs
jfs
jfs_tune -L "new label" /dev/XXX 使用 jfsutils
xfs
xfs_admin -L "new label" /dev/XXX 使用 xfsprogs
fat/vfat
fatlabel /dev/XXX "new label" 使用 dosfstools
mlabel -i /dev/XXX ::"new label" 使用 mtools
exfat
tune.exfat -L "new label" /dev/XXX 使用 exfatprogs
exfatlabel /dev/XXX "new label" 使用 exfatprogsexfat-utils
ntfs
ntfslabel /dev/XXX "new label" 使用 ntfs-3g
udf
udflabel /dev/XXX "new label" 使用 udftools
crypto_LUKS (LUKS2 only)
cryptsetup config --label="new label" /dev/XXX 使用 cryptsetup

可以通過 lsblk 獲得設備的標籤:

$ lsblk -dno LABEL /dev/sda2
Arch Linux	
注意:
  • 修改文件系統的標籤時不能掛載它。對於 root 文件系統,這可以通過從另一個卷引導來完成。
  • 標籤必須是唯一的,以防止可能的衝突。
  • 標籤最多可以有16個字符。
  • 標籤是文件系統的一個屬性,所以無法持久地表示單一磁盤陣列設備。
  • 在使用 dm-crypt 的加密容器時,容器內的文件系統的標籤在容器被鎖定/加密時是不可用的。

通過 uuid[編輯 | 編輯原始碼]

UUID 是一種為每個文件系統提供唯一標識符的機制。這些標識符是在設備被格式化時,通過文件系統工具生成的 (例如 mkfs.*),並且在設計上不太可能發生衝突。所有 GNU/Linux 文件系統 (包括 swap 和 LUKS headers 或 原始加密設備) 都支持 UUID。FAT,exFAT 和 NTFS 文件系統不支持 UUID,但是依舊會有一個較短的 UID (唯一標識符) 在 /dev/disk/by-uuid/ 中列出:

$ 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
lrwxrwxrwx 1 root root 10 May 27 23:31 F4CA-5D75 -> ../../mmcblk0p1

可以通過 lsblk 獲取設備的 UUID:

$ lsblk -dno UUID /dev/sda1
CBB6-24F2

或使用 blkid:

# blkid -s UUID -o value /dev/sda1
CBB6-24F2

使用 UUID 方法的優勢在於,與使用標籤相比,發生名稱衝突的可能性要小得多。此外,它是在創建文件系統時自動生成的。舉個例子,即使設備插入另一個系統 (那個系統上可能有一個具有相同標籤的設備),它也會保持唯一。

這個方法的壞處是 UUID 使長代碼行難以閱讀並破壞許多配置文件中的格式 (例如 fstabcrypttab)。此外,每次重新格式化卷時都會生成一個新的 UUID,並且必須手動調整配置文件。

提示:如果您的交換卷沒有分配 UUID,你將需要使用 mkswap 工具來重置它。

通過 id 和 通過路徑[編輯 | 編輯原始碼]

by-id 會依據硬件序列號創建一個唯一的名字,by-path 則取決於最短的物理路徑 (根據 sysfs)。兩者都包含字符串以指示它們屬於哪個子系統 (例如對於 by-path 來説是 -ide-,對於 by-id 來説是 -ata-),因此它們與控制設備的硬件相關聯。這意味着不同級別的持久性: by-path 會在設備插入控制器的不同端口時改變,by-id 會在設備插入受另一個子系統約束的硬件控制器的端口時改變。[1]因此,兩者都不適合實現針對硬件更改的持久化命名。

然而,兩者都提供了在大型硬件基礎設施中查找特定設備的重要信息。舉個例子,如果你沒有手動分配持久性的標籤 (by-labelby-partlabel) 而且保留有一個包含硬件端口使用情況的目錄,by-idby-path 就可以用於找到特定的設備。[2] [3]

by-id 還會創建支持 World Wide Name 的存儲設備的連結。不像其它 by-id 連結, WWN 是完全持久化而且不會因使用的子系統改變。

這篇文章的某些內容需要擴充。

原因: 解釋並提供關於 /dev/disk/by-id/nvme-eui.* 連結[4]的例子。NVME 設備的 WWID 是否總是以 eui. 開頭? (在 Talk:塊設備持久化命名 中討論)
注意: by-idby-path 連結只能被視為磁盤持久化,而不是分區。分區將通過其在分區表中的編號進行引用,並且如果對分區重新排序,該編號可能會發生變化。
$ ls -l /dev/disk/by-id/
total 0
lrwxrwxrwx 1 root root 10 May 27 23:31 ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470 -> ../../sda
lrwxrwxrwx 1 root root 10 May 27 23:31 ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 May 27 23:31 ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 May 27 23:31 ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 May 27 23:31 ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 May 27 23:31 mmc-SD32G_0x0040006d -> ../../mmcblk0
lrwxrwxrwx 1 root root 10 May 27 23:31 mmc-SD32G_0x0040006d-part1 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 10 May 27 23:31 wwn-0x60015ee0000b237f -> ../../sda
lrwxrwxrwx 1 root root 10 May 27 23:31 wwn-0x60015ee0000b237f-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 May 27 23:31 wwn-0x60015ee0000b237f-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 May 27 23:31 wwn-0x60015ee0000b237f-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 May 27 23:31 wwn-0x60015ee0000b237f-part4 -> ../../sda4
$ ls -l /dev/disk/by-path/
total 0
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:00:1f.2-ata-1 -> ../../sda
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:00:1f.2-ata-1-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:00:1f.2-ata-1-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:00:1f.2-ata-1-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:00:1f.2-ata-1-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:07:00.0-platform-rtsx_pci_sdmmc.0 -> ../../mmcblk0
lrwxrwxrwx 1 root root 10 May 27 23:31 pci-0000:07:00.0-platform-rtsx_pci_sdmmc.0-part1 -> ../../mmcblk0p1

通過分區標籤[編輯 | 編輯原始碼]

注意: 此方法僅涉及具有 GUID 分區表的磁盤。

在 GPT 磁盤上,GPT 分區標籤可以在分區條目的 header 中定義。

這個方法與文件系統標籤很相似,但是即使分區上的文件系統發生更改,分區標籤也不會受到影響。

$ 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

設備的分區標籤可以用 lsblk 獲取:

$ lsblk -dno PARTLABEL /dev/sda1
EFI system partition

或使用 blkid:

# blkid -s PARTLABEL -o value /dev/sda1
EFI system partition
注意:
  • GPT 分區標籤也需要各不相同來避免衝突。要想改變分區標籤,你可以使用 gdisk 或 基於 ncurse 的版本 cgdisk。它們都可通過 gptfdisk 軟件包獲取。請見 Partitioning#分區工具
  • 根據規範,GPT 分區標籤最多可以有 72 字符長。

通過分區 uuid[編輯 | 編輯原始碼]

注意: 此方法僅涉及具有 GUID 分區表的磁盤。

就像 GPT 分區標籤,在 GPT 磁盤上,GPT 分區 UUID 在分區條目中定義。

MBR 不支持分區 UUID,但是 Linux[5] 和軟件使用 libblkid[6] (例如 udev[7]) 能夠為 MBR 分區生成偽分區 UUID。其格式為 SSSSSSSS-PP,SSSSSSSS 是一個零填充的 32 位 MBR 磁盤簽名,而 PP 則是一個十六進制形式的零填充分區號。和一般的 GPT 分區的分區 UUID 不同,MBR 的偽分區 UUID 會在分區改變時改變。

動態目錄與其它方法相似,就像 文件系統 UUID,比起標籤更推薦使用 UUID。

$ ls -l /dev/disk/by-partuuid/
total 0
lrwxrwxrwx 1 root root 10 May 27 23:31 0003e1e5-01 -> ../../mmcblk0p1
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


設備的分區 UUID 可以用 lsblk 獲得:

$ lsblk -dno PARTUUID /dev/sda1
d0d0d110-0a71-4ed6-936a-304969ea36af


或使用 blkid:

# blkid -s PARTUUID -o value /dev/sda1
d0d0d110-0a71-4ed6-936a-304969ea36af

使用 Udev 靜態設備名[編輯 | 編輯原始碼]

參考 設置靜態設備名[損壞的連結:無效的章節]

使用持久名稱[編輯 | 編輯原始碼]

有多種應用可以配置為使用持久名稱。下面列出了一些配置的例子:

fstab[編輯 | 編輯原始碼]

請見主文章: fstab#文件系統標識

內核參數[編輯 | 編輯原始碼]

要在內核參數中使用持久化名稱,需要滿足下列先決條件。在遵循安裝指南的標準安裝中,需滿足兩個條件:

root 文件系統的位置在內核命令行中是通過參數 root 傳遞的。內核命令行是通過引導加載程序配置的,請見 內核參數#配置。要想修改為持久化設備名,只需修改用於指定塊設備的參數,例如 rootresume,而其它參數則保持不變。支持多種命名方案:

在這個以 Arch Linux 為 root 文件系統標籤的例子中展示了使用標籤的持久化設備名 和 LABEL= 格式。

root="LABEL=Arch Linux"

在這個以 0a3407de-014b-458b-b5c1-848e92a327a3 為 root 文件系統 UUID 的例子中展示了使用 uuid 的持久化設備名 和 UUID= 格式。

root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3

在這個以 wwn-0x60015ee0000b237f-part2 為 root 分區 id 的例子中展示了使用磁盤 id 的持久化設備名 和 /dev 路徑格式。

root=/dev/disk/by-id/wwn-0x60015ee0000b237f-part2

在這個以 98a81274-10f7-40db-872a-03df048df366 為 root 分區的分區 UUID 的例子中展示了使用 GPT 分區 UUID 的持久化設備名 和 PARTUUID= 格式。

root=PARTUUID=98a81274-10f7-40db-872a-03df048df366

在這個以 GNU/Linux 為 root 分區的分區標籤的例子中展示了使用 GPT 分區標籤的持久化設備名 和 PARTLABEL= 格式。

root="PARTLABEL=GNU/Linux"