一、 OverlayFS 是一项什么样的技术?
简单来说,OverlayFS 是一种**“联合挂载”技术,它可以把多个目录叠加在一起,让用户看到一个“合并后”**的目录视图。
为了理解它,我们可以用一个经典的**“透明胶片”**类比:
- Lowerdir(底层):就像一张印刷好的底片。这是你的只读系统分区(比如 SquashFS),里面存放着系统原本的程序和配置。这张底片是不能修改的。
- Upperdir(上层):就像一张覆盖在底片上的透明胶片。这是你的可读写分区(比如 Data 分区)。所有的修改、新增、删除,都记录在这张透明胶片上。
- Merged(合并层):这是用户看到的最终效果。当你透过透明胶片看底片时,你看到的是两者的叠加。
核心机制:写时复制
OverlayFS 最核心的魔法在于它如何处理“修改”:
- 读取文件:直接去底层读。
- 新建文件:直接写在上层。
- 修改文件:
- 如果文件在底层(只读区),OverlayFS 会先把文件复制一份到上层。
- 然后在上层的这个副本上进行修改。
- 之后读取时,系统会优先读取上层的副本,底层的原件被“遮盖”了,但依然完好无损。
- 删除文件:
- 并不真的删除底层文件,而是在上层创建一个**“Whiteout”标记**(一种字符设备文件),告诉系统“这个文件不存在了”。
结论:无论你如何折腾系统(修改配置、删除程序),底层的只读分区永远干干净净,掉电重启后,如果上层损坏,丢弃上层即可恢复出厂设置。
二、 为了使用这个技术,你需要做什么?
要在你的嵌入式设备上实现“只读系统 + 可写配置”的 OverlayFS 方案,你需要做以下四个步骤的准备。
第 1 步:内核配置(软件准备)
首先,你的 Linux 内核必须支持 OverlayFS。
- 进入内核配置菜单:
makemenuconfig - 找到并启用以下选项:
File systems ---> <*> Overlay filesystem support - 重新编译内核并更新到设备。
第 2 步:存储分区规划(硬件准备)
延续之前的例子,你需要把 eMMC 划分为两个主要区域(Bootloader 暂且不表):
- 分区 A (rootfs_ro):存放系统本体。
- 文件系统:推荐SquashFS(压缩只读,极其安全)。
- 挂载点:
/ro(系统内部的一个隐藏目录)。
- 分区 B (rootfs_rw):存放数据、日志、配置变更。
- 文件系统:ext4或f2fs。
- 挂载点:
/rw(系统内部的一个隐藏目录)。
第 3 步:构建目录结构
在系统启动脚本(如rcS或init脚本)中,你需要准备好 OverlayFS 所需的“原材料”。
OverlayFS 需要三个目录参数:
lowerdir:指向只读分区挂载的地方。upperdir:指向读写分区中专门存放“修改数据”的目录。workdir:OverlayFS 内部工作时需要的临时目录(必须和 upperdir 在同一个文件系统下)。
假设你已经把分区 A 挂载到了/ro,把分区 B 挂载到了/rw。你需要创建子目录:
# 在读写分区创建 upper 和 work 目录mkdir-p/rw/uppermkdir-p/rw/work第 4 步:执行挂载与切换根目录
这是最关键的一步,你需要把这两个目录“融合”,并变成系统的根目录/。
通常这需要在系统启动的早期(init 阶段)完成。逻辑如下:
- 先将只读分区挂载到
/ro。 - 将读写分区挂载到
/rw。 - 挂载 OverlayFS 到一个新的目录(例如
/newroot)。 - 切换根目录到
/newroot。
Shell 脚本示例(简化版):
# 1. 挂载物理分区mount-tsquashfs /dev/mmcblk0p2 /ro# 只读系统挂到 /romount-text4 /dev/mmcblk0p3 /rw# 读写数据挂到 /rw# 2. 准备 Overlay 所需目录mkdir-p/rw/uppermkdir-p/rw/work# 3. 挂载 OverlayFS# lowerdir=/ro : 底层是只读系统# upperdir=/rw/upper : 所有的修改存这里# workdir=/rw/work : 工作目录mount-toverlay overlay-olowerdir=/ro,upperdir=/rw/upper,workdir=/rw/work /newroot# 4. 切换根目录# 将 /newroot 变成新的根目录 /execswitch_root /newroot /sbin/init三、 实际操作演示
假设你按照上述配置启动了系统。
场景 1:修改/etc/hostname
- 原始文件在
/ro/etc/hostname(内容为 “device-default”)。 - 你执行
echo "my-device" > /etc/hostname。 - OverlayFS 检测到你要修改底层文件,于是:
- 将
/ro/etc/hostname复制到/rw/upper/etc/hostname。 - 修改
/rw/upper/etc/hostname为 “my-device”。
- 将
- 你再读
/etc/hostname,看到的是 “my-device”。 - 掉电测试:如果此时掉电,
/rw分区可能损坏,但/ro分区里的 “device-default” 完好无损。修复或清空/rw后,系统恢复默认值。
场景 2:新增日志文件/var/log/test.log
/var/log通常在只读分区里是不存在的,或者是空的。- 你写入文件,OverlayFS 直接在
/rw/upper/var/log/下创建文件。 - 底层完全不受影响。
总结
使用 OverlayFS,你实际上是在构建一个**“三明治”**:
- 面包底:只读的系统镜像(安全、压缩、掉电无损)。
- 肉饼:OverlayFS 驱动(负责分发读写请求)。
- 面包顶:用户的修改数据(可读写、掉电可能丢失但可修复)。
这样,你既拥有了 Linux 系统丰富的文件操作能力,又拥有了像 RTOS(实时操作系统)那样刷不死的“金刚不坏之身”。