OverlayFS

OverlayFS 简介

OverlayFS (Overlay Filesystem) 是一种联合文件系统(Union Filesystem),它允许用户将一个文件系统(通常是可写的)“覆盖”在另一个文件系统(通常是只读的)之上。对于用户来说,这两个文件系统看起来像是一个合并后的单一目录树。

OverlayFS 在 Linux 内核 3.18 中被合并进主线,因其设计简洁、性能高效而被广泛应用于容器技术(如 Docker)和嵌入式系统(如 OpenWrt)。

核心概念

OverlayFS 主要涉及四个目录层级:

  • Lower Dir (底层目录): 通常是只读的。 在 OpenWrt 中,这通常对应于压缩的只读固件部分(SquashFS)。 可以有多个 Lower 层。

  • Upper Dir (上层目录): 是可写的。 所有对文件系统的修改(新建、修改、删除)都会记录在这里。 在 OpenWrt 中,这通常对应于 JFFS2 或 UBIFS 分区。

  • Work Dir (工作目录): 一个对用户不可见的空目录,OverlayFS 使用它来准备文件操作(如原子性保证)。 必须与 Upper Dir 在同一个文件系统下。

  • Merged Dir (合并目录): 这是用户最终看到的挂载点。 它展示了 Lower 和 Upper 合并后的视图。

工作原理

  • 读取 (Read): 如果文件在 Upper 层存在,直接读取 Upper 层的文件。 如果文件仅在 Lower 层存在,读取 Lower 层的文件。 如果两层都有,Upper 层的文件会“遮盖”住 Lower 层的文件。

  • 写入 (Write):

    • 修改文件: 当尝试修改一个位于 Lower 层的文件时,OverlayFS 会触发 Copy-Up 操作,将文件从 Lower 层复制到 Upper 层,然后对 Upper 层的文件进行修改。
    • 新建文件: 直接在 Upper 层创建。
  • 删除 (Delete): 如果删除的是 Upper 层的文件,直接删除。 如果删除的是 Lower 层的文件,OverlayFS 会在 Upper 层创建一个特殊的 Whiteout 文件(通常是字符设备 0/0),用于标记该文件已被“遮盖”(即删除),从而在 Merged 视图中不可见。


OpenWrt 中的 OverlayFS 应用

OpenWrt 是 OverlayFS 最经典的落地场景之一。它利用 OverlayFS 完美解决了嵌入式设备存储空间有限且需要系统恢复能力的矛盾。

OpenWrt 的文件系统架构

OpenWrt 的固件通常包含两个主要部分:

  • /rom (Read-Only): 这是一个 SquashFS 文件系统,包含了系统启动所需的所有基础文件、内核模块和默认配置。 它是高度压缩的,且在运行时是只读的。这保证了系统核心文件的安全性,无论用户如何误操作,都可以恢复出厂设置。

  • /overlay (Read-Write): 这是一个 JFFS2 (对于 NOR Flash) 或 UBIFS (对于 NAND Flash) 文件系统,或者是 ext4 (对于 SD 卡/硬盘)。 它用于存储用户的配置更改、安装的软件包等。

挂载机制

当 OpenWrt 启动时,它会执行以下逻辑(简化版):

  • 挂载 SquashFS 分区到 /rom
  • 挂载可写分区(如 JFFS2)到 /overlay
  • 使用 OverlayFS 将 /overlay(Upper)覆盖在 /rom(Lower)之上,并将结果挂载到根目录 /

挂载命令示例:

1
mount -t overlay overlay -o lowerdir=/rom,upperdir=/overlay/upper,workdir=/overlay/work /

(注:OpenWrt 的实际挂载过程由 mount_rootpreinit 脚本处理,细节可能因版本而异,早期版本使用 mini_fo,现代版本均使用 overlayfs)*

实际操作与管理

查看挂载状态

在 OpenWrt 终端中输入 df -hmount 可以看到 OverlayFS 的结构:

1
2
3
4
5
6
root@OpenWrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.5M      2.5M         0 100% /rom
tmpfs                    61.8M    168.0K     61.6M   0% /tmp
/dev/mtdblock3            5.0M    424.0K      4.6M   8% /overlay
overlayfs:/overlay        5.0M    424.0K      4.6M   8% /

可以看到 / 的类型是 overlayfs:/overlay,它的大小等于 /overlay 分区的大小。

恢复出厂设置 (Firstboot)

由于 OverlayFS 的特性,恢复出厂设置变得非常简单:只需要清空 /overlay 分区即可。

/overlay 被清空后,Upper 层没有了任何文件,系统重启后,OverlayFS 呈现的完全是 Lower 层(即 /rom)的内容,系统就回到了初始状态。

命令:

1
2
firstboot -y
reboot

扩容 (Extroot)

OpenWrt 设备的内置 Flash 通常很小(如 16MB)。利用 OverlayFS,我们可以轻松实现扩容(Extroot):

  • 插入一个 USB U盘。
  • 将 U盘格式化为 ext4。
  • 将 U盘挂载为 /overlay
  • 这样,系统的可用空间就变成了 U盘的大小,可以安装大量的软件包。

常见问题

空间不足: 如果 /overlay 满了,系统可能无法保存配置或安装软件。此时删除文件实际上是在 Upper 层操作。 文件被遮挡: 如果你在 /rom 中修改了源码重新编译固件,但刷机后发现文件没变,可能是因为 /overlay 中存在旧的修改版本遮挡了新的 /rom 文件。刷机时通常建议选择“不保留配置”来清空 /overlay

总结

OverlayFS 是 OpenWrt 灵活性的基石。它通过分层机制,既保证了系统底层的稳定性(只读的 /rom),又提供了用户所需的灵活性(可写的 /overlay),并且实现了极低成本的“恢复出厂设置”功能。理解 OverlayFS 对于深入玩转 OpenWrt(如定制固件、扩容、调试)至关重要。

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计