永続的なブロックデバイスの命名
この記事ではブロックデバイスに永続的な名前を使う方法を説明します。永続的な命名は udev の導入によって可能になったものであり、バスによる命名と比べて複数の利点があります。同じ命名スキームを持つドライブがマシン上に複数存在する場合、それらに対応するデバイスノードが追加される順序は任意です。そのため、起動するたびにデバイス名 (例: /dev/sda
と /dev/sdb
、/dev/nvme0n1
と /dev/nvme1n1
、/dev/mmcblk0
と /dev/mmcblk1
) が入れ替わる可能性があり、下手をすると、システムが起動できなくなったり、カーネルパニックが発生したり、ブロックデバイスが表示されなくなってしまいます。永続的な命名によってこれらの問題は解決します。
目次
永続的な命名の方法
udev (60-persistent-storage.rules
) によって永続的な命名に使用されるスキームは4つあります: by-label、by-uuid、by-id と by-path。GUID Partition Table (GPT) のディスクを使用する場合、さらに by-partlabel と by-partuuid の形式も利用可能です。
/dev/disk/
内のディレクトリは、デバイスがあるかどうかに応じて動的に作成・破棄されます。
以下のセクションではこれらの異なる命名規則がどのようなものであるか、またどうやって使うのかを説明しています。
lsblk コマンドを使うことで1つ目の永続的な名前をグラフィカルに表示することができます:
$ 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
GPT を使っている場合、代わりに blkid
コマンドを使います。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"
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 Arch\x20Linux -> ../../sda2
ほとんどのファイルシステムは、ファイルシステム作成時におけるラベルの設定をサポートしています (関連する mkfs.*
ユーティリティの man ページを参照してください)。一部のファイルシステムにおいてはラベルを変更することもできます。以下は、一般的なファイルシステムにおけるラベルの変更方法です:
- btrfs
- btrfs-progs で
btrfs filesystem label /dev/XXX "new label"
(デバイスをすでにマウントしている場合は、そのマウントポイントを使用してください) - crypto_LUKS (LUKS2 のみ)
- cryptsetup で
cryptsetup config --label="new label" /dev/XXX
- exfat
- exfatprogs で
tune.exfat -L "new label" /dev/XXX
- exfatprogs または exfat-utils で
exfatlabel /dev/XXX "new label"
- ext2/3/4
- e2fsprogs で
e2label /dev/XXX "new label"
- fat/vfat
- dosfstools で
fatlabel /dev/XXX "new label"
- mtools で
mlabel -i /dev/XXX ::"new label"
- jfs
- jfsutils で
jfs_tune -L "new label" /dev/XXX
- ntfs
- ntfs-3g で
ntfslabel /dev/XXX "new label"
- reiserfs
- reiserfsprogs で
reiserfstune -l "new label" /dev/XXX
- swap
- util-linux で
swaplabel -L "new label" /dev/XXX
- udf
- udftools で
udflabel /dev/XXX "new label"
- xfs
- xfsprogs で
xfs_admin -L "new label" /dev/XXX
(デバイスをすでにマウントしている場合は、そのマウントポイントを使用してください)
デバイスのラベルは lsblk を使って得ることができます:
$ lsblk -dno LABEL /dev/sda2
Arch Linux
あるいは blkid を使って:
# blkid -s LABEL -o value /dev/sda2
Arch Linux
by-uuid
UUID は、各ファイルシステムにユニークな識別子を与えるための仕組みです。UUID 識別子は、パーティションをフォーマットするときにファイルシステムユーティリティ (例: mkfs.*
) によって生成されます。UUID 識別子は衝突が起こりにくいように作られています。(スワップや生の暗号化デバイスの LUKS ヘッダを含む) 全ての GNU/Linux ファイルシステムが UUID をサポートします。FAT、exFAT、NTFS ファイルシステムは UUID をサポートしていませんが、それでも、より短い UID (unique identifier) で /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
デバイスの UUID は lsblk を使って得ることができます:
$ lsblk -dno UUID /dev/sda1
CBB6-24F2
あるいは blkid を使って:
# blkid -s UUID -o value /dev/sda1
CBB6-24F2
UUID を使用する利点として、名前の衝突が発生する可能性がラベルよりもずっと少ないことが挙げられます。さらに、UUID はファイルシステムの作成時に自動的に生成されます。他のシステムにデバイスを接続したときでも、一意性を保つことができます。ラベルの場合、他のシステムに接続したとき名前がカブってしまう可能性が否定できません。
逆に UUID の欠点としては、生成されるコードが長いために、設定ファイル (例: fstab や crypttab) が読みづらくなったり整形が崩れてしまうことがあります。また、パーティションのサイズを変更したり、再フォーマットをするたびに新しい UUID が生成されるので、設定を手動で変更する必要が生じます。
by-id と by-path
by-id
はハードウェアのシリアル番号に基づいて一意な名前を作成します。by-path
は (sysfs による) 一番短い物理パスを使います。どちらも、属するサブシステムを示す文字列を含んでいるため (by-path
の場合 -ide-
、by-id
の場合 -ata-
)、デバイスを制御するハードウェアと繋がりがあります。このため永続性のレベルが異なってきます: by-path
はデバイスをコントローラの他のポートに接続したときに値が変わり、by-id
はデバイスを他のサブシステムが使っているハードウェアコントローラのポートに接続したときに値が変わります。[1] 従って、ハードウェアが変わっても値が変わらないような永続的な命名としてはどちらも不適切です。
しかし、巨大なハードウェア基盤で特定のデバイスを見つけたいときに、どちらも有益な情報を提供します。例えば、永続的なラベル (by-label
や by-partlabel
) を手動で割り当てず、ハードウェアポートの使用を表すディレクトリが変わらない場合、by-id
と by-path
を使うことで特定のデバイスを探すことが可能です。[2] [3]
$ 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 13 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T -> ../../nvme1n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T-part1 -> ../../nvme1n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T-part2 -> ../../nvme1n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T_1 -> ../../nvme1n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T_1-part1 -> ../../nvme1n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0N704064T_1-part2 -> ../../nvme1n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268 -> ../../nvme0n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268-part1 -> ../../nvme0n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268-part2 -> ../../nvme0n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268_1 -> ../../nvme0n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268_1-part1 -> ../../nvme0n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-WDS100T1X0E-00AFY0_21455A801268_2-part2 -> ../../nvme0n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-eui.002538570142d716 -> ../../nvme1n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.002538570142d716-part1 -> ../../nvme1n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.002538570142d716-part2 -> ../../nvme1n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a -> ../../nvme0n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a-part1 -> ../../nvme0n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a-part2 -> ../../nvme0n1p2 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 13 May 27 23:31 pci-0000:01:00.0-nvme-1 -> ../../nvme0n1 lrwxrwxrwx 1 root root 15 May 27 23:31 pci-0000:01:00.0-nvme-1-part1 -> ../../nvme0n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 pci-0000:01:00.0-nvme-1-part2 -> ../../nvme0n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 pci-0000:04:00.0-nvme-1 -> ../../nvme1n1 lrwxrwxrwx 1 root root 15 May 27 23:31 pci-0000:04:00.0-nvme-1-part1 -> ../../nvme1n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 pci-0000:04:00.0-nvme-1-part2 -> ../../nvme1n1p2 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
World Wide Name
by-id
はストレージデバイスの World Wide Name (WWN) のリンクも作成します (そのデバイスが WWN をサポートしている場合)。他の by-id
リンクとは異なり、WWN は完全に永続的であり、使用されているサブシステムに依らず変化しません。
SATA と SAS のデバイスには wwn-
プレフィックスが付きますが、NVMe デバイスでは別の WWN 形式が使用され nvme-eui.
というプレフィックスが付きます。[4]
$ ls -l /dev/disk/by-id/{wwn-,nvme-eui.}*
lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-eui.002538570142d716 -> ../../nvme1n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.002538570142d716-part1 -> ../../nvme1n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.002538570142d716-part2 -> ../../nvme1n1p2 lrwxrwxrwx 1 root root 13 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a -> ../../nvme0n1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a-part1 -> ../../nvme0n1p1 lrwxrwxrwx 1 root root 15 May 27 23:31 nvme-eui.e8238fa6bf530001001b448b4566aa1a-part2 -> ../../nvme0n1p2 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
by-partlabel
パーティションラベルは、GPT ディスクのパーティションエントリのヘッダで定義することができます。
この方法はファイルシステムラベルと非常に似ています。しかし、パーティションラベルは、パーティション上のファイルシステムが変更された場合でも、影響を受けません。
パーティションラベルを持つ全パーティションは /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
デバイスのパーティションラベルは lsblk を使って得ることができます:
$ lsblk -dno PARTLABEL /dev/sda1
EFI system partition
あるいは blkid を使って:
# blkid -s PARTLABEL -o value /dev/sda1
EFI system partition
by-partuuid
GPT パーティションラベルのように、GPT パーティション UUID も GPT ディスク上のパーティションエントリで定義されます。
MBR はパーティション UUID をサポートしていません。しかし、Linux[5] と、libblkid[6] を使用するソフトウェア (例: udev[7]) は、MBR パーティションに対して擬似的な PARTUUID を生成することができます。この時、形式は SSSSSSSS-PP
となります。SSSSSSSS
の部分はゼロで埋められた32ビットの MBR ディスクシグネチャで、PP
はゼロで埋められた16進形式のパーティション番号です。GPT パーティションの通常の PARTUUID と違って、MBR の疑似 PARTUUID は、パーティション番号が変更された場合に変わる可能性があります。
動的ディレクトリは他の方法のものと似ており、ファイルシステム 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
永続的な命名の使用
様々なアプリケーションで、永続的な命名を使うように設定を行うことができます。以下はアプリケーションの設定例です。
fstab
メインの記事を参照してください: fstab#ファイルシステムの識別。
カーネルパラメータ
永続的な名前をカーネルパラメータで使用するには、以下の前提条件を満たさなければなりません。インストールガイドに従った標準的なインストールでは、以下の両方の前提条件を満たしています:
- udev が含まれている initramfs イメージを使用していること
- mkinitcpio の場合、
udev
かsystemd
のどちらか一方のフックを/etc/mkinitcpio.conf
で有効化していること
ルートファイルシステムの場所はカーネルコマンドラインで root
パラメータを使って渡します。カーネルコマンドラインはブートローダーから設定します。カーネルパラメータ#ブートローダーの設定 を参照してください。永続的なデバイスの命名に変更するには、ブロックデバイスを指定するパラメータ (例: root
と resume
) のみを変更して、他のパラメータはそのままにしてください。様々な命名規則がサポートされています:
ラベルを用いたデバイスの永続的な命名と LABEL=
形式。以下の例では、Arch Linux
がルートファイルシステムの LABEL になっています:
root="LABEL=Arch Linux"
UUID を用いたデバイスの永続的な命名と UUID=
形式。以下の例では、0a3407de-014b-458b-b5c1-848e92a327a3
がルートファイルシステムの UUID になっています:
root=UUID=0a3407de-014b-458b-b5c1-848e92a327a3
ディスク id を用いたデバイスの永続的な命名と /dev
パス形式。以下の例では、wwn-0x60015ee0000b237f-part2
がルートパーティションの id になっています。
root=/dev/disk/by-id/wwn-0x60015ee0000b237f-part2
GPT パーティション UUID を用いたデバイスの永続的な命名と PARTUUID=
形式。以下の例では、98a81274-10f7-40db-872a-03df048df366
がルートパーティションの PARTUUID になっています。
root=PARTUUID=98a81274-10f7-40db-872a-03df048df366
GPT パーティションラベルを用いたデバイスの永続的な命名と PARTLABEL=
形式。以下の例では、GNU/Linux
がルートパーティションの PARTLABEL になっています。
root="PARTLABEL=GNU/Linux"