本文通过“准备一份基础环境镜像”的例子,浅谈 EROFS(Enhanced Read-Only File System)。

为便于理解,下面以启用压缩的只读镜像为例,不展开制作命令、压缩算法和底层数据结构。

What

先把最容易混淆的一点说清楚:

1
2
3
文件数据以压缩形式保存
≠
使用前必须把整个镜像全部解压

EROFS 是 Linux 的一种只读文件系统,支持将目录和文件制作成可以直接挂载使用的镜像。

可以简单理解为:

1
2
3
制作时:把准备好的目录和文件组织成镜像

使用时:挂载镜像,按路径访问其中的文件

挂载后,应用看到的仍然是普通的目录和文件;需要读取压缩数据时,由文件系统完成相应的解压。

所以:

不是先把整个镜像解开再使用,而是挂载后,按需读取里面的文件。

注意,压缩是可选功能,不是所有 EROFS 镜像都必须压缩。

Why

操作系统文件、预装工具、基础运行环境等内容,往往在准备好后反复读取,并不需要每次运行时修改。

对于这类数据,我们既希望它们少占磁盘,又希望程序可以方便地读取,而不是每次使用前都先完整解包。

EROFS 的目标并不只是“压得越小越好”,还要尽量控制读取时的 I/O、解压计算和额外内存开销。

因此,它的目的可以概括为:

把只读文件保存得更紧凑,同时让程序能够直接、高效地读取。

基础 Example

假设一份基础环境包含:

1
2
3
4
基础环境
bin/tool
lib/libdemo.so
etc/config.ini

现在,应用只需要读取 etc/config.ini。

先完整解包再使用

假设采用“把压缩包完整解到目录中,再启动应用”的部署方式:

1
2
3
4
5
基础环境压缩包
↓
完整解包到一个目录
↓
应用读取 etc/config.ini

这条路径中,即使本次只需要一个文件,也先展开了整套环境。

使用 EROFS 镜像

1
2
3
4
5
6
7
base.erofs
↓
挂载到 /mnt/base
↓
应用读取 /mnt/base/etc/config.ini
↓
文件系统读取所需的数据,必要时解压

不需要为了读取这个配置文件,先把 bin/tool 和 lib/libdemo.so 全部解出来。

区别就在于:

省掉的是使用前的整包解压和文件落盘,不是所有解压操作。

How

只看三个关键点。

1. 制作镜像时,先组织好目录和文件

通过 mkfs.erofs,可以把已有目录制作成 EROFS 镜像。

镜像不仅保存文件内容,也保存目录结构、文件属性以及定位数据所需的信息。启用压缩后,文件数据可以以压缩形式存放。

1
2
3
4
5
原有目录和文件
↓
制作 EROFS 镜像
↓
目录信息 + 文件信息 + 文件数据

之后挂载镜像,就能按原来的目录结构访问其中的文件。

2. 读取文件时,按需定位和解压

以相关数据尚未被缓存为例,可以把读取过程简化为:

1
2
3
4
5
6
7
应用读取某个文件的一段内容
↓
EROFS 定位对应的数据区域
↓
读取相关数据;如果经过压缩,则进行解压
↓
将文件内容交给应用

应用仍然使用普通的文件读取接口,不需要自己解析镜像或调用解压库。

这里的“按需”是以相关数据块为单位,不代表应用读取几个字节,底层就恰好只读取、解压几个字节。

3. 尽量减少读取和解压的额外工作

压缩文件系统需要解决一个问题:

1
2
3
应用只想读一小段内容
↓
却可能连带读取、解压更多数据

EROFS 在压缩数据布局和解压路径上做了专门优化,尽量减少这类额外读取,并减少解压过程中的临时内存和数据拷贝。

可以简单理解为:

不仅考虑“存起来占多少空间”,也考虑“读出来要花多少代价”。

与 OverlayFS 的关系

结合上一篇介绍的 OverlayFS,两者可以这样分工:

1
2
3
EROFS:保存只读的基础内容

OverlayFS:将这些内容与可写上层组合起来

例如:

1
2
3
4
5
6
7
8
       应用看到的目录
│
OverlayFS
│
┌────────┴────────┐
▼ ▼
可写上层 EROFS 只读下层
保存运行时改动 提供基础文件

应用需要修改下层文件时,由 OverlayFS 按需复制到可写上层,再修改上层副本。

不是 EROFS 自己变得可写了,而是写入由另一个可写文件系统承接。

记忆图

1
2
3
4
5
6
7
8
准备阶段:
目录和文件 → 制作镜像,可选择压缩

使用阶段:
挂载镜像 → 按路径访问 → 按需读取,必要时解压

需要修改:
配合 OverlayFS → 将改动留在可写上层

一句话概括:

把只读文件做成可以直接挂载的镜像,需要什么就读取什么,不必先把整套内容解开。


参考资料:

  1. Linux Kernel Documentation: EROFS
  2. EROFS Documentation: Build & Mount
  3. EROFS Documentation: Frequently Asked Questions
  4. EROFS: A Compression-friendly Readonly File System for Resource-scarce Devices — USENIX ATC 2019
  5. Linux Kernel Documentation: Overlay Filesystem