问题

系统启动后,磁盘分区不会挂载,无论是计划内的还是计划外的。
在重新启动之前,磁盘分区已安装并正常工作。
其他系统重新启动后,磁盘已正确挂载,但不再起作用。

无论分区上的文件系统类型如何,这种行为都可能发生,并且与文件系统类型无关。
已经报告了 EXT4 或者 OCFS2 文件系统的磁盘故障,但任何文件系统类型都可能发生故障。

/etc/fstab 文件中的典型条目可能类似于:

/dev/sda1          /mydir    ext4   defaults  0 0
/dev/mapper/mpath2 /otherdir ocfs2  _netdev   0 0

或者这些的各种组合。

解决方案

磁盘驱动器和分区在 Linux 中根据它们的总线位置和发现顺序按地理位置进行寻址。
由于 SAN 或者客户端的重启时间不同,SAN 设备特别容易受到发现顺序更改的影响。

Linux 上的文件名,通常在 /dev/ 目录中,在每次系统启动时动态分配。
当内核启动时,检测到每个可用设备,并向 UDEV(用户空间设备管理)子系统发送通知。
通过将内核设备标识中的信息与 /etc/udev/rules.d 目录中的 UDEV 规则集进行比较,UDEV 为设备分配一个名称并创建一个设备节点,例如 /dev/sda 或者 /dev/mapper/mpath1 等应用程序可以访问设备。
如果检测到的设备是块结构设备,则它通常具有包含文件系统的分区,这些文件系统可以根据 /etc/fstab 文件中的规范进行安装。

尽管 Linux 已尽一切努力在系统重新启动时保持相同的设备名称,但外部环境的变化可能会影响实际的名称选择。
例如:同一个 SAN 分区在一个客户端上可能是 /dev/sda,但在另一个集群节点上可能是 /dev/sdf,这取决于每个主机发现设备的顺序,或者多路径链接首先联机。
节点通常在每次启动时以相同的顺序发现其设备,但这并不能保证。
需要一种方法来保证持久的、可预测的设备识别。

尽管 Linux 尝试在每次重新启动时重新分配相同的设备名称,但在集群节点之间没有这种协调。
在一个集群节点上可靠地显示为 /dev/sda1 的分区可以轻松且合法地在另一个集群节点上始终显示为 /dev/sdj。
这会使集群范围的系统管理变得比需要的更困难。
下面提供的解决方案也适用于不会发生此重启问题的集群。

可以使用替代技术来获得持久的、可预测的设备名称。
它们按难度排列如下。

更多: zhilu jiaocheng

按标签安装

许多文件系统类型支持将任意字符串或者标签与每个文件系统相关联。
EXT3 文件系统是一个例子:

# /sbin/e2label /dev/sda5
/home

通常会看到类似于以下内容的 /etc/fstab 条目:

LABEL=/HOME /home auto defaults 0 0

找到标记为 /HOME 的磁盘分区,无论它出现在哪个设备上。

OCFS2 文件系统还提供了一个可识别的标签,可以类似地使用。
有关如何确定 OCFS2 标签的信息,请参阅下面的 OCFS2 示例。

使用 UDEV 规则集

另一种获得持久的、可预测的设备名称的方法是利用内核用来分配设备名称的相同 UDEV 服务。
这涉及创建一个 UDEV 匹配规则,该规则使用设备属性来识别设备,然后为其创建一个设备节点。
通常,该规则只是创建到内核分配的实际低级设备节点的符号链接。

这是用于实现设备映射器多路径设备的技术。
内核创建一个 /dev/dm-X 设备;然后 UDEV 规则和多路径守护进程创建 /dev/mpath/ 链接回 /dev/dm-X 设备;然后创建 /dev/mapper/mpathN 或者 /dev/mapper/[uuid>] 链接。

创建哪种类型的 /dev/mapper/ 文件名由 /etc/multipath.conf 文件 user_friendly_names 设置控制。
默认设置为:

default {
    user_friendly_names yes
}

奇怪的是,它创建了完全没有意义的 /dev/mapper/mpathN 名称。
通过注释掉这一点,使用了更具气势的 /dev/mapper/ 表单名称。
它们可能更难输入,但至少它们可以跨所有集群节点移植。

以下是 UDEV 匹配规则的示例。
该行以一系列谓词或者匹配表达式开始;这些由“==”运算符标记。
如果所有谓词都与发现的设备的谓词匹配,则采取“=”子句表示的操作。

SYSFS{vendor}=="iriver" SYSFS{model}=="T10" OWNER="user" MODE="0600" SYMLINK+="iriver%n"

本示例在第一个 IRiver T10 播放器插入 USB 端口时创建符号链接 /dev/iriver0。
该设备将由具有文件访问权限 0600 的用户拥有。
USB 子系统通知设备已插入并通知内核;发现的有关设备的属性也会传递给内核。
此信息最终到达 UDEV 子系统,该子系统开始读取 /etc/udev/rules.d 中的规则集并将设备属性与每个规则的谓词进行匹配。
如果所有谓词都与规则匹配,则执行该规则指定的任何操作。

有关 UDEV 系统的文档,包括编写 UDEV 规则的语法,可通过 udev 手册页在线获取。

编写 UDEV 规则的挑战性部分是了解哪些属性可用,以便规则可以正确识别设备。
udevinfo 实用程序将显示规则可用的设备名称和属性。
对于我们的示例,检查 /var/log/messages 显示 IRiver 设备被检测为块设备并分配了名称 /dev/sdb。
现在,我们可以通过查看 /block/sdb 系统信息来获取所有设备信息和属性:

# /usr/bin/udevinfo -q all -p /block/sdb
P: /block/sdb
N: sdb
S: disk/by-id/usb-iriver_T10
S: disk/by-path/pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0
E: ID_VENDOR=iriver
E: ID_MODEL=T10
E: ID_REVISION=1.00
E: ID_SERIAL=iriver_T10
E: ID_TYPE=disk
E: ID_BUS=usb
E: ID_PATH=pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0

请注意,路径是相对于 /sys/ 目录的,而不是传统的根目录。
完整的文件名将是 /sys/block/sdb 但 udevinfo 假定为 /sys 部分。

选择最少的属性集可能很棘手,但要避免过度指定的诱惑。
我们这里的选择是使用供应商名称和型号名称,但可以使用任何标识对象设备的属性集。
一旦选择了谓词和动作,将规则放在 /etc/udev/rules.d 目录中的它们自己的文件中。
不要修改发行版中的规则集,否则更新包时更改可能会丢失。
在我们的示例中,我们使用 /etc/udev/rules.d/49-iriver.rules 作为文件名。

设置好 UDEV 规则后,使用 udevtest 实用程序模拟 UDEV 运行并显示将执行的操作。

通过 UUID 挂载

许多文件系统类型为每个格式化的磁盘分区分配一个通用唯一标识符或者 UUID。
EXT3 和 OCFS2 文件系统就是这样的例子。
UUID 通常是自动分配的,通常不鼓励系统管理员手动更改该值。

在 EXT3 和其他类型的文件系统上,使用作为 e2fsprogs RPM 包的一部分提供的 blkid 实用程序。
对于我们的示例,输出如下所示:

# /sbin/blkid /dev/sda5
/dev/sda5: LABEL="/home" UUID="0c960108-7649-4d8c-a28c-2f75e2f906d3" SEC_TYPE="ext2" TYPE="ext3"

请注意,严格来说,UUID 只是十六进制数字。
“-”字符只是要被忽略的标点符号。

在 OCFS2 文件系统上,UUID 始终由 fsck.ocfs2 实用程序报告。
如果使用“-n”开关来确保只读测试,则可以安全地在已安装的磁盘分区上使用此实用程序:

# /sbin/fsck.ocfs2 -n /dev/hda1
Checking OCFS2 filesystem in /dev/hda1:
label: OCFS2
uuid: bc d0 de d0 58 ea 43 11 bd a9 e0 66 e6 cb 37 b4 
number of blocks: 209632
bytes per block: 1024
number of clusters: 52408
bytes per cluster: 4096
max slots: 4
/dev/hda1 is clean. It will be checked after 20 additional mounts.

再次注意,UUID 本身是一串十六进制数字。
在这里它们被空格打断,但真正的 UUID 只是数字。
要获得 UUID,一个简短的 awk(1) 程序就足够了:

# /sbin/fsck.ocfs2 -n /dev/hda1 | /bin/awk '/uuid/ {  = ""; gsub( / /, "" ); print }'
bcd0ded058ea4311bda9e066e6cb37b4

现在我们有了 UUID,像这样的 /etc/fstab 条目将挂载 EXT3 或者 OCFS2 分区:

UUID=bcd0ded058ea4311bda9e066e6cb37b4   /ocfs2 ocfs2 _netdev  0 2
UUID=0c96010876494d8ca28c2f75e2f906d3 /home  ext3  defaults 0 2

由于 UUID 存储在磁盘分区本身中,因此实际设备名称是否更改并不重要,我们有一种保证持久、可预测的方法来访问它。

在Linux中重新启动时由于设备名称不一致导致挂载失败或者不正确
日期:2020-09-17 00:14:00 来源:oir作者:oir