2. 磁盘设备识别与命名
在 RHEL 存储与文件系统管理中,一切操作都从“找到正确的块设备”开始。Linux 把块设备抽象为 /dev 下的设备节点,但不同总线、不同驱动、不同虚拟化平台下,内核给出的命名规则并不相同。理解 /dev/sdX、/dev/nvmeXnY、/dev/vdX 三类命名的来源,是避免“误格式化系统盘”“挂错盘”等事故的第一道防线。
三类命名规则的本质差异
/dev/sdX 来自 SCSI 子系统,包括 SATA、SAS、USB 存储以及多数硬件 RAID 逻辑盘。命名格式为 sd + 字母 + 可选分区号,例如 /dev/sda、/dev/sdb、/dev/sda1。字母按内核探测到设备的先后顺序分配,顺序本身不稳定:新增一块盘、更换插槽、调整 BIOS 启动顺序,都可能导致 sda 与 sdb 互换。
/dev/nvmeXnY 来自 NVMe 驱动,格式为 nvme + 控制器编号 + n + 命名空间编号,例如 /dev/nvme0n1 表示第 0 个控制器的第 1 个命名空间。分区在其后追加 p 与分区号,如 /dev/nvme0n1p1。注意 NVMe 分区用 p 分隔,而 sd/vd 直接拼接数字,这是最容易写错的地方。
/dev/vdX 来自 virtio-blk 驱动,常见于 KVM/QEMU 虚拟机,格式为 vd + 字母,如 /dev/vda、/dev/vdb。它同样按探测顺序分配字母,因此也存在顺序漂移问题。三类命名都遵循“设备节点 + 分区后缀”的结构,但前缀和分区分隔符不同,脚本中若硬编码 /dev/sda1,迁移到 NVMe 机器上必然失败。
lsblk:先看清拓扑再动手
lsblk 是最先应该执行的命令,它以树形展示块设备、分区、挂载点和容量。默认输出不含文件系统类型,加上 -f 可显示 FSTYPE、UUID、LABEL、MOUNTPOINT:
[root@rhel ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs boot 3f2a1c8e-... /boot
└─sda2 LVM2_member 8b7d4e21-...
├─rhel-root xfs a1c9f0d3-... /
└─rhel-swap swap 5e2b7a44-... [SWAP]
nvme0n1
└─nvme0n1p1 xfs data 9d4c1b77-... /data
vda
└─vda1 xfs c7e3a912-... /
从输出可以读出关键信息:sda2 是 LVM 物理卷,其上是 rhel-root 逻辑卷;nvme0n1p1 是独立 XFS 分区;vda1 是虚拟机系统盘。若只想看某块盘,可用 lsblk /dev/nvme0n1;若需要脚本解析,用 lsblk -P -o NAME,SIZE,TYPE,MOUNTPOINT 输出 KEY="value" 格式更稳妥。
blkid:拿到 UUID 与文件系统类型
blkid 直接读取块设备上的超级块信息,输出 UUID、TYPE、LABEL、PARTUUID。它需要 root 权限才能读取全部设备:
[root@rhel ~]# blkid /dev/nvme0n1p1
/dev/nvme0n1p1: UUID="9d4c1b77-2e5a-4f01-9c3d-6a8b1e2f7d40" TYPE="xfs" LABEL="data"
[root@rhel ~]# blkid -s UUID -o value /dev/nvme0n1p1
9d4c1b77-2e5a-4f01-9c3d-6a8b1e2f7d40
UUID 在文件系统创建时生成,只要不重新格式化就保持不变,因此是 fstab 中最可靠的引用方式。LABEL 可人为设置(xfs_admin -L 或 e2label),便于人类识别,但需保证唯一性。注意:blkid 对未格式化的裸设备不会输出 UUID,此时应先确认是否真的要创建文件系统。
udevadm:追溯设备属性与稳定链路
udevadm info 用于查询 udev 数据库中某设备的属性,是排查“为什么这块盘没有生成 by-id 链接”的关键工具:
[root@rhel ~]# udevadm info --query=all --name=/dev/nvme0n1p1
P: /devices/pci0000:00/0000:00:04.0/nvme/nvme0/nvme0n1/nvme0n1p1
N: nvme0n1p1
S: disk/by-uuid/9d4c1b77-2e5a-4f01-9c3d-6a8b1e2f7d40
S: disk/by-partuuid/3a7f2c10-01
E: ID_FS_TYPE=xfs
E: ID_FS_UUID=9d4c1b77-2e5a-4f01-9c3d-6a8b1e2f7d40
E: ID_SERIAL=INTEL_SSDPEKKW256G8_BTNH12345678
其中 P 是设备在 sysfs 中的路径,N 是内核设备名,S 是 udev 创建的符号链接,E 是环境属性。ID_SERIAL 来自硬件序列号,是 by-id 链接的命名依据。若某块盘没有 by-id 链接,通常说明该设备未上报稳定序列号,此时应改用 by-path 或 UUID。
另一个常用命令是 udevadm monitor --udev --property,在插拔设备时实时打印 udev 事件与属性,适合验证新盘是否被正确识别。而 udevadm trigger 可强制重新触发规则,用于修复链接缺失。
持久化命名实践
内核顺序名(sda/vda)不可靠,持久化命名目录位于 /dev/disk/ 下,常见四类:
by-uuid/:按文件系统 UUID,最稳定,推荐用于 fstab。by-label/:按文件系统标签,可读性好,需保证唯一。by-id/:按设备序列号或 WWN,适合整盘引用(如 LVM、裸设备)。by-path/:按物理路径(PCI 插槽),适合固定硬件的服务器。
实际写 fstab 时,应使用 UUID 而非设备名。例如把 /dev/nvme0n1p1 挂到 /data:
# 错误写法:顺序变化后可能挂错盘
/dev/nvme0n1p1 /data xfs defaults 0 0
# 正确写法:使用 UUID
UUID=9d4c1b77-2e5a-4f01-9c3d-6a8b1e2f7d40 /data xfs defaults 0 0
验证方式:执行 mount -a 无报错,再用 findmnt /data 确认挂载来源为 /dev/disk/by-uuid/...。若需在脚本中引用整盘,可用 /dev/disk/by-id/ 下的链接,例如 /dev/disk/by-id/nvme-INTEL_SSDPEKKW256G8_BTNH12345678。
lsblk -f 看拓扑与挂载,blkid 取 UUID/TYPE,udevadm info 查属性与链接来源;fstab 一律用 UUID 或 LABEL,脚本引用整盘用 by-id,固定槽位用 by-path。mkfs 或 wipefs 前,务必先用 lsblk -f 与 blkid 双重确认设备名、容量、现有文件系统和挂载点,避免误伤系统盘或已有数据盘。