把 fstab 的六个字段写准
一句话总结
fstab 的一行由设备 / 挂载点 / 类型 / 选项 / dump / pass 六个字段组成。随意填写最后两个数字,确实可能导致系统卡在启动过程中。
为什么需要了解这一点
fstab 是系统中最危险的文件之一。写错后,系统可能在启动途中停住;如果没有控制台,甚至无从处理。但它的格式看起来很简单,所以人们常常随手复制粘贴。
工作原理
UUID=1a2b... /srv/data ext4 defaults,noatime,nofail 0 2
[----1----] [---2---] [-3-] [--------4---------] 5 6
1. 设备标识符。 可以是 UUID=、LABEL=、PARTUUID= 或设备路径。网络文件系统则使用 server:/export 形式。设备路径不稳定,因此应使用 UUID。
2. 挂载点。 必须是绝对路径。路径中有空格时,用 \040 转义。
3. 文件系统类型。 包括 ext4、xfs、tmpfs、nfs4、none(绑定挂载)和 auto。
4. 选项。 以逗号分隔。常用选项如下。
| 选项 | 含义 | 使用场景 |
|---|---|---|
defaults |
rw,suid,dev,exec,auto,nouser,async | 默认 |
noatime |
读取时不更新时间戳 | 推荐用于大多数服务器 |
nofail |
即使挂载失败也继续启动 | 数据磁盘必需 |
_netdev |
网络就绪后再挂载 | NFS/iSCSI 必需 |
noexec,nosuid,nodev |
禁止执行、setuid 和设备文件 | /tmp、用户上传路径 |
ro |
只读 | 受审计的数据 |
bind |
绑定挂载 | 见下文 |
如果没有 nofail,一块数据盘损坏就会导致整台服务器无法启动。 对几乎所有非根文件系统条目来说,它都是必需的。
5. dump。 供旧式 dump 备份工具使用的标志。现在几乎总是填写 0。
6. pass——fsck 检查顺序。 这才是真正的陷阱。
| 值 | 含义 |
|---|---|
0 |
不检查(tmpfs、NFS、绑定挂载) |
1 |
只用于根文件系统。 最先单独检查 |
2 |
其他本地文件系统。在 1 完成后并行检查 |
非根文件系统若填写 1, 启动时多个文件系统会试图同时接受单独检查,导致顺序混乱。网络文件系统若填写 1 或 2, 会在网络尚未就绪的启动早期尝试检查,从而卡住。
绑定挂载
把同一文件系统中的一个目录同时显示在另一条路径上。
/srv/data /var/www/data none bind 0 0
它与符号链接有什么不同?符号链接保存的是路径字符串,而绑定挂载是真正的挂载。 因此,在 chroot 或容器内部等路径解析范围受限的环境中,符号链接可能失效,绑定挂载仍能工作。绑定挂载还可设置 ro 等独立选项——原始位置可写,而只在这条路径中显示为只读。
验证
修改 fstab 后,重启前必须验证。通过重启来确认不是验证,而是赌博。
findmnt --verify --verbose
mount -a # 실제로 붙여 본다 (특권 필요)
实际工作中的表现
NFS 条目遗漏 _netdev。 系统启动时会在网络就绪前尝试挂载,并一直等待到超时,使服务器启动多花五分钟。
扩容后没有修改 fstab。 已经扩展 LVM 并执行 resize2fs,重启后容量却又回到旧大小?实际上是 fstab 一直指向另一块卷。
systemd 会读取 fstab
在现代 Linux 中,fstab 本身并不执行;启动时由 systemd 读取并转换成挂载单元。理解这一点后,两件事就容易解释。
第一,可以用 systemctl status 查看挂载状态。/srv/data 会变成名为 srv-data.mount 的单元(路径中的斜杠变为短横线)。挂载失败时,通过 journalctl -u srv-data.mount 查看原因,会比只盯着 fstab 得到更具体的信息。
第二,fstab 的一部分选项其实是给 systemd 的指令。nofail 表示挂载失败也不阻塞其他单元;_netdev 表示把顺序延后到网络就绪之后。以 x-systemd. 开头的选项则完全是 systemd 专用。实务中尤其有价值的有两个。
x-systemd.automount——启动时不挂载,真正访问该路径时才挂载。 特别适合速度慢或偶尔不可用的网络存储,启动不会因此延迟。x-systemd.device-timeout=10s——缩短等待设备的时间。默认值是 90 秒,一个不存在的设备就可能长时间拖住启动。
还有一点也很容易忘记:修改 fstab 后必须通知 systemd 重新读取。 若不执行 systemctl daemon-reload,systemd 仍会保留旧单元,于是可能出现 mount -a 能挂载、重启后行为却不同的混乱状态。养成把前面提到的 findmnt --verify、mount -a 和这条命令合在一起,用三行完成验证的习惯,几乎就能杜绝因 fstab 导致启动停止的事故。
下个练习将做什么
按照规则审计损坏的 fstab 固件,找到有问题的行并修复,然后亲自编写验证脚本。评分器会分别用正常输入和错误输入运行该脚本,确认它能否正确判断。