RustROS · 2026-10-26 · 主线 fa150c7

M6 报告:容器镜像

镜像可以导入了:docker save 的 tar、OCI 镜像布局(tar 或目录)都能读,每个 blob 和每一层都校验摘要,层解到 files 分区的 ext4 上,不同镜像共用相同的层;从镜像叠出根文件系统后,真实的 debian:trixie 镜像里 bash、apt-get update、apt-get install 都能用。镜像工具是一个用户态程序,内核和模块接口都没改。

回归测试(KVM 测试机)48 项全部通过新增 images 测试;单元测试 186 项;转发 TCP 19.5 / 19.2 Gbit/s,64 B 364 / 380 kpps
debian:trixie(124 MB)导入 15–19 s叠成根文件系统 11 s(5448 项),在测试机的嵌套虚拟机里
镜像工具652 KBRust 标准库、静态链接 musl 的用户态程序,跑在 Linux 兼容层上
这次更新不用重启内核代码没变;只换 vfs 模块(修了一个目录读取的问题)

M6做了什么

步骤内容验收
M6.1userland/:随系统提供的用户态程序的工作区(Rust 标准库、静态 musl);images 程序:load、ls、inspect、tag、rm、rootfs;存储在 /var/lib/rustros/images(层按 diff_id 存、镜像、标签;先写临时名字再改名)单元测试:tar 解析(PAX、GNU 长名字、校验和)、路径安全、删除标记和不透明目录、硬链接
M6.2解包(自己写的 tar 读取)和叠根文件系统:普通文件、目录、符号链接、硬链接、设备、FIFO;属主、权限(含 setuid)、时间;删除标记 .wh.、不透明目录合成镜像(三层,覆盖上述各种情况)以三种格式导入:同一个镜像、层只存一份;叠出的根目录逐项核对类型、权限、属主、内容、硬链接、设备号,删掉的确实不在;层内容和摘要不符被拒绝;层里经符号链接往外写被拒绝
M6.3真实镜像:测试机用自己写的 Python 从 Docker Hub 取 debian:trixie(linux/amd64,存在工作目录里)导入、叠出根文件系统,在里面跑 bash、apt-get update、apt-get install hello、hello;删除镜像连同层;导入进行中把进程杀掉,存储里没有半个镜像,再导入成功
测试中发现VFS:一边读目录一边删其中的项(Rust 的 remove_dir_all、rm -r 都这样做)时,后面的项会被跳过,删目录失败(Directory not empty)。现在删除时把正在读这个目录的句柄的位置往回调VFS 单元测试(40 个文件,边读边删);images rm

为什么做成用户态程序:解包是对不可信输入(tar、gzip、JSON)的大量处理,放在 ring 3 出错只影响它自己;只用已有的文件系统调用,不用改内核和模块接口,这个里程碑不用重启;顺便检验了兼容层(Rust 标准库的程序第一次在 RustROS 上跑)。

内核这次内核改了什么(按新规则报告)

遗留还没有的

缺口打算
用户态程序怎么随发布分发(现在测试时直接放进 files 分区)M7b:和 docker 命令一起,作为发布里的一种新条目,pkg 装到 /usr/lib/rustros/
容器的根文件系统现在是整份复制(rootfs)M7a 决定:VFS 里做叠加视图(各层只读、容器一层可写),复制作为后备
从仓库拉取(registry pull)、docker save 导出按计划在后;测试里的 Python 拉取可以作为参考流程
zstd 压缩的层;扩展属性(文件能力,如 ping 的 cap_net_raw)按需

请你确认

M6 是否发布:这次不用重启(内核沿用,只更新 vfs 模块;镜像工具先不随发布分发,见遗留)。之后按顺序是 M7a(通用容器核心:隔离的根目录和 PID 空间、根文件系统、网络接入、资源限制、生命周期、状态交接)。M7a 开始前我会先发设计请你确认里面的几个决定(根文件系统用叠加视图还是复制、PID 空间的做法)。