在同一挂载点挂载备用设备(具有不同挂载选项)

ali*_*i_m 5 linux ubuntu automounting mount fstab

我有一台带有热插拔驱动器托架的服务器(运行 Ubuntu 14.04)。我通常使用热插拔托架来安装一堆松散的硬盘中的一个,我在上面穿梭大型科学数据集。其中一些磁盘需要不同的挂载选项(不同的文件系统、SSD 与 HDD 等),我通常会为/etc/fstab.

为了简化我的一些用于批处理和备份这些数据的脚本,我想将服务器配置为始终对当前插入的这些热插拔磁盘中的任何一个使用相同的挂载点。

我试过把这样的东西放在我的fstab

UUID=<disk A>  /common_mount_point  ext4   defaults,discard,noatime  0 0
UUID=<disk B>  /common_mount_point  btrfs  defaults,compress=lzo     0 0    
Run Code Online (Sandbox Code Playgroud)

当我想挂载磁盘 A 时,这工作正常,但是每当我尝试挂载磁盘 B 时,我都会收到错误消息:

mount: special device UUID=<disk B> does not exist
Run Code Online (Sandbox Code Playgroud)

如果我交换这两行的顺序,则会发生相反的情况,因此似乎mount只是查找fstab引用该特定挂载点的第一行,如果找不到关联的文件系统描述符,则会引发错误。

我想我可以编写一个 bash 脚本来依次尝试将几个不同的 UUID 挂载到同一个挂载点,直到其中一个挂载操作成功,但我希望有一个更优雅的解决方案。

更新 1

有趣的是,如果我调用sudo mount -a而不是mount /common_mount_point,虽然我仍然收到无法找到磁盘 A 的 UUID 的错误消息,但它会成功安装磁盘 B。因此似乎mount -a会尝试fstab使用相同的安装点的多个条目,但我会而不必sudo为了使这项工作。

这种行为似乎与此报告的bugmountall,这是明显地固定于V2.50。Trusty 存储库中的最新版本仍然是 2.49,所以我会看看是否可以找到具有更新版本的 PPA。

更新 2

事实证明,该错误mountall无关紧要,因为mountall仅在我调用mount -a而不是mount /common_mount_point. 事实上mountall,根据输出dpkg -s mountall(尽管mountall --version告诉我它是 v2.49),我已经在运行v2.53 。这大概解释了sudo mount -a确实尝试fstab引用同一挂载点的多行的事实。

Gil*_*il' 3

利用 udev 使用相同的设备名称

您可以列出/etc/fstab设备名称,并将 udev 设置为对所有这些设备使用相同的设备名称,而不是在 中列出 UUID。将这样的行放入以下文件中/etc/udev/rules.d

KERNEL=="sd*", ATTRS{serial}=="123456798", NAME="one_of_my_disks%n"
Run Code Online (Sandbox Code Playgroud)

或者

KERNEL=="sd*", ATTRS{serial}=="123456798", SYMLINK+="one_of_my_disks%n"
Run Code Online (Sandbox Code Playgroud)

运行udevadm info -a -n sdb以查看可以匹配的磁盘属性(如上ATTRS{serial}=="123456798"例)。请注意,您只能使用多个属性,但它们都必须来自同一部分。

然后,在 中/etc/fstab,用作/dev/one_of_my_disks块设备。

如果您的磁盘具有不同的布局,则情况会更加复杂。您可以用于auto文件系统类型;这应该适用于大多数类型。但是,如果您需要不同的分区号或安装选项,则需要不同的 fstab 条目。您可以通过 udev 条目调用的脚本进行动态编辑来解决这个问题fstab,该脚本将在系统检测到磁盘时执行。例如,使用以下 udev 规则:

KERNEL=="sd*", ATTRS{serial}=="123456798", ENV{FSTAB4}="compress=lzo", NAME="one_of_my_disks%n", RUN+="/usr/local/sbin/fstab_update_my_disk"
Run Code Online (Sandbox Code Playgroud)

和以下fstab_update_my_disk脚本(未经测试):

#!/bin/sh
/usr/bin/sed -i -e '/^\/dev\/one_of_my_disks1/ s/\([^ \t][^ \t]*[ \t][ \t]*[^ \t][^ \t]*[ \t][ \t]*[^ \t][^ \t]*[ \t][ \t]*\)[^ \t][^ \t]*/\1'"$FSTAB4"'/'
Run Code Online (Sandbox Code Playgroud)

利用 udev 不关心挂载点

另一种方法是保留单独的 fstab 条目,具有不同的设备名称和不同的安装点。但使用 udevRUN挂钩来更新指向挂载点的符号链接。

KERNEL=="sd*", ATTRS{serial}=="123456798", RUN+="/bin/ln -snf /media/disk1 /media/one_of_my_disks"
Run Code Online (Sandbox Code Playgroud)