原文地址: https://www.tony-yin.site/201...
众所周知,我们看到的磁盘通常是/dev/sda
,/dev/sdb
这样的名称,我们可以通过这些磁盘名称对磁盘进行各种操作,例如挂载,分区和格式化等等。但是,如果你的机器上有不止一个SATA
,SCSI
或IDE
磁盘控制器,那么它们所对应的设备节点将会依随机次序添加。这样就可能导致每次引导时设备的名字如/dev/sda
与/dev/sdb
互换了,再比如硬盘拔插导致磁盘乱序等等,最终导致系统不可引导、kernel panic
、或者设备不可见。持久化命名可以解决这些问题。
概述
持久化命名,顾名思义即一次性或者是短暂的命名,它是一种长久的并且稳定靠谱的命名方案。与之形成鲜明对比的就是/dev/sda
这种非持久化命名,这两种命名方案各有各的用处,本文着重对持久化命名进行介绍。持久化命名方案有四种:by-label
、by-uuid
、by-id
和by-path
。对于那些使用GUID
分区表(GPT
)的磁盘,还有额外的两种方案:by-partlabel
和by-partuuid
。你也可以使用Udev
静态设备名方案,这个我们就不作详细解释。下面我将对每种持久化命名方案进行详细的介绍和讲解,不难发现上面所提到的命名方式在/dev
目录下都存在一个与之名字对应的文件夹:
by-label
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
标签必须是唯一的,标签是文件系统的一个属性,所以无法持久地表示单一磁盘阵列设备。
注意:label
是通过从设备中的内容(即数据)获取,所以如果将该内容拷贝至另一个设备中,我们也可以通过blkid
来获取磁盘的label
。
by-uuid
UUID
是给每个文件系统唯一标识的一种机制,这个标识是在分区格式化时通过文件系统工具生成,比如mkfs
,这个唯一标识可以起到解决冲突的作用。所有GNU/Linux
文件系统(包括swap
和原始加密设备的LUKS
头)都支持UUID
。FAT
和NTFS
文件系统并不支持UUID
,但是在/dev/disk/by-uuid
目录下还是存在着一个更为简单的UID
(唯一标识)。
$ 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
使用UUID
方法的优点是,名称冲突发生的可能性大大低于使用Label
的方式。更深层次地讲,它是在创建文件系统时自动生成的。例如,即使设备插入到另一个系统(可能有一个标签相同的设备),它仍然是唯一的。
缺点是uuid
使得许多配置文件(例如fstab
或crypttab
)中的长代码行难以读取和破坏格式。此外,每当一个分区被调整大小或重新格式化时,都会生成一个新的UUID,并且必须(手动)调整配置。
by-path
该目录中的条目提供一个符号名称,该符号名称通过用于访问设备的硬件路径引用存储设备,首先引用PCI hierachy
中的存储控制器,并包括SCSI host
、channel
、target
和LUN
号,以及可选的分区号。虽然这些名字比使用major
和minor
号或sd
名字更容易,但必须使用谨慎以确保target
号不改变在光纤通道SAN
环境中(例如,通过使用持久绑定),如果一个主机适配器切换到到一个不同的PCI
插槽的话这个路径也会随之改变。此外,如果HBA
无法探测,或者如果驱动程序以不同的顺序加载,或者系统上安装了新的HBA
,那么SCSI
主机号都有可能会发生变化。附带路径清单的一个例子是:
/dev/disk/by-path/pci-0000:03:00.0-scsi-0:1:0:0
也许还会带着分区号:
/dev/disk/by-path/pci-0000:03:00.0-scsi-0:1:0:0-part1
注意: 上面说了很多种情况都会导致by-path
的值可能发生变化,但是在同一时间来说,by-path
的值是和物理设备是唯一对应的,也就是说不管怎么说by-path
是对应物理机器上面的某个位置的,根据by-path
可以获取对应物理位置的设备。(此前megaraid
通过逻辑磁盘获取物理磁盘位置就是根据这个原理)
对于iSCSI
设备,路径/名称映射从目标名称和门户信息映射到sd
名称。
应用程序通常不适合使用这些基于路径的名称。这是因为这些路径引用可能会更改存储设备,从而可能导致将不正确的数据写入设备。基于路径的名称也不适用于多路径设备,因为基于路径的名称可能被误认为是单独的存储设备,导致不协调的访问和数据的意外修改。
此外,基于路径的名称是特定于系统的。当设备被多个系统访问时,例如在集群中,这会导致意外的数据更改。
by-id
此目录中的条目提供一个符号名称,该符号名称通过唯一标识符(与所有其他存储设备不同)引用存储设备。标识符是设备的属性,但不存储在设备的内容(即数据)中。例如:
/dev/disk/by-id/scsi-3600508e000000000ce506dc50ab0ad05
/dev/disk/by-id/wwn-0x600508e000000000ce506dc50ab0ad05
该id
从设备的全局ID
(WWID
)或设备序列号中获取。/dev/disk/by-id
条目也可能包含一个分区号。例如:
/dev/disk/by-id/scsi-3600508e000000000ce506dc50ab0ad05-part1
/dev/disk/by-id/wwn-0x600508e000000000ce506dc50ab0ad05-part1
World Wide Identifier
(WWID
)可用于可靠的识别设备。SCSI
标准要求所有SCSI
设备提供一个持久的、系统无关的ID
。WWID
标识符保证对每个存储设备都是唯一的,并且独立于用于访问设备的路径。
这个标识符可以通过发出SCSI
查询来获取设备标识重要厂商数据(第0x83
页)或单位序列号(第0x80
页)。从这些wwid
到当前/dev/sd
名称的映射可以在/dev/disk/by-id/
目录中维护的符号链接中看到。
例如,具有页0x83
标识符的设备将具有:
scsi-3600508b400105e210000900000490000 -> ../../sda
或者,具有页0x80
标识符的设备将具有:
scsi-SSEAGATE_ST373453LW_3HW1RHM6 -> ../../sda
Red Hat Enterprise Linux 5
自动维护从基于wwid
的设备名称到系统上当前/dev/sd
名称的正确映射。应用程序可以使用/dev/ disk/by-id/
的链接引用磁盘上的数据,即使设备的路径改变,甚至当从不同系统访问该设备时都是如此。
但是当设备被插入到硬件控制器的端口时,而这个端口又受另一个子系统控制(即多路径),by-id
的值也会改变。多路径设备会在下面详细讲解。
by-partlabel && by-partuuid
这两个和上面提到的by-label
和by-uuid
类似,只不过是在GPT
磁盘上。
多路径设备
所谓多路径设备指的是从一个系统到一个设备存在多个路径,这种现象主要出现在光纤网络的SAN
下,主要是做数据链路冗余以达到高可用的效果,即对应底层一个物理设备,可能存在多个路径表示它,具体参考refer
下面有关文章。
如果从一个系统到一个设备有多个路径,那么 device-mapper-multipath
使用WWID
来检测它。然后在/dev/mapper/wwid
中显示一个“伪设备”,例如/dev/ mapper/3600508b400105df70000000ac0000
。
Device-mapper-multipath
显示映射到非持久标识符:Host:Channel:Target:LUN
, /dev/sd
名称,以及major:minor
号。
3600508b400105df70000e00000ac0000 dm-2 vendor,product
[size=20G][features=1 queue_if_no_path][hwhandler=0][rw]
\_ round-robin 0 [prio=0][active]
\_ 5:0:1:1 sdc 8:32 [active][undef]
\_ 6:0:1:1 sdg 8:96 [active][undef]
\_ round-robin 0 [prio=0][enabled]
\_ 5:0:0:1 sdb 8:16 [active][undef]
\_ 6:0:0:1 sdf 8:80 [active][undef]
Device-mapper-multipath
在系统上自动维护每个基于wwid
的设备名称和其对应的/dev/sd
名称的正确映射。这些名称即使是在路径发生改变时也是持久的,并且当从不同的系统访问设备时它们仍然是一致的。
总结
为了方便管理和使用设备,linux
操作系统给我们提供了上面这么多持久化命名方式。它们各自有各自的优势和使用场景。by-label
和by-uuid
都和文件系统相关,by-label
是通过读取设备中的内容获取,by-uuid
则是随着每次文件系统的创建而创建,所以by-uuid
的持久化程度更高一些;持久化程度最高的要属by-path
和by-id
了,因为它们都是根据物理设备的位置或者信息而和链接做对应的,by-path
会因为路径的变化而变化;而by-id
则不会因为路径或者系统的改变而改变,它只会在多路径的情况下发生改变。这两个在通过虚拟设备名称寻找物理设备的场景下都十分有用。
多路径设备则帮助我们在SAN
等场景下提高了数据传输的可用性,目前由于网络带宽的发展,它在iscsi
场景下也频繁亮相。