fix(starry): report ENOSYS for the unimplemented new mount API#1241
Conversation
There was a problem hiding this comment.
审查总结
变更内容:将 fsopen / fspick / open_tree 三个新挂载 API 的 syscall 处理从 sys_dummy_fd(返回假 fd)改为直接返回 Err(AxError::Unsupported)(映射为 ENOSYS)。同时新增回归测试 bugfix-bug-mount-api-enosys。
实现逻辑:修复前,sys_dummy_fd 为非 qemu 进程返回一个假 fd,systemd 探测到 fsopen "成功" 后认为内核支持新挂载 API,继续调用未实现的 fsconfig 导致失败且不会回退到经典 mount(2)。修复后,三个入口直接返回 ENOSYS,systemd 可正确检测到新 API 不可用并回退。这与 sys_dummy_fd 中对 qemu 进程的诚实策略一致。
代码审查:
components/axerrno/src/lib.rs第 260 行确认AxError::Unsupported映射到LinuxError::ENOSYS,handle_syscall的unwrap_or_else正确将错误转换为-ENOSYS返回用户态。修改正确且完整。- 注释清晰解释了 systemd fallback 语义和为什么不能返回假 fd。
fsconfig/fsmount/move_mount本就落入默认分支返回 ENOSYS,行为现在一致。
测试验证:
- 新增 C 回归测试通过 raw
syscall()直接调用 fsopen/fspick/open_tree,断言返回-1且errno == ENOSYS。修复前返回假 fd(≥ 0)会 FAIL,从而钉住行为。 - CMakeLists.txt 将二进制安装到
usr/bin/starry-test-suit,与qemu-*/toml的自动发现路径一致,会被所有架构(x86_64/aarch64/riscv64/loongarch64)的 system runner 自动执行。 - 测试使用
_GNU_SOURCE+#ifndef回退定义,syscall 编号(428/430/433)在所有架构上一致。
CI 状态:
- Detect changed paths: ✅ success
- Run sync-lint / run_container: ✅ success
- Cancel stale CI runs: ✅ success
- Check formatting / run_host: 排队中(runner 可用性问题,非失败)
- 其余检查为预期的 skipped(路径过滤 / 互斥 job)
- 无 CI 失败。
重复/重叠分析:未发现其他 open PR 修改 fsopen/fspick/open_tree 或 mount API 相关代码。PR #1240(monotonic deadlines)和 PR #1239 与此 PR 无交集。
回归覆盖:bug-fix PR 附带了回归测试,测试在修复前会失败(返回假 fd),修复后通过(返回 ENOSYS)。满足回归覆盖要求。
无阻塞问题,建议合并。
Powered by mimo-v2.5-pro
ZR233
left a comment
There was a problem hiding this comment.
复查当前 head 4fc0b265c,本轮没有发现阻塞问题,Approve。
审查要点:
- 变更范围清晰:
fsopen/fspick/open_tree不再走sys_dummy_fd返回假 fd,而是直接返回AxError::Unsupported,用户态映射为ENOSYS;同时新增qemu-smp1/system/bugfix-bug-mount-api-enosys回归测试。 - 实现逻辑符合当前 Starry/systemd 兼容目标:这些新 mount API 入口尚未实现,返回假 fd 会让 systemd 误判能力并进入后续
fsconfig路径;直接返回ENOSYS能让它回退到已有的经典mount(2)。AxError::Unsupported -> LinuxError::ENOSYS的映射也已核对。 - 回归覆盖有效:新增测试使用 raw
syscall()直接断言fsopen、fspick、open_tree返回-1且errno == ENOSYS;修复前 dummy fd 路径会返回非负 fd,因此会被这个测试抓到。 - Starry grouped case 接入正确:
CMakeLists.txt安装到usr/bin/starry-test-suit,显式cargo xtask starry test qemu --arch x86_64 -c qemu-smp1/bugfix-bug-mount-api-enosys --list能选中qemu-smp1/systemgrouped case。
本地验证:
cargo fmt --check passed
git diff --check origin/dev...HEAD passed
rg -n '[patch.crates-io]' -g Cargo.toml no hits
git merge-tree origin/dev HEAD no conflict messages
cargo xtask clippy --package starry-kernel passed 13/13
cargo xtask starry test qemu --arch x86_64 \
-c qemu-smp1/bugfix-bug-mount-api-enosys passed, 1/1 case(s)
QEMU guest 中实际输出了 PASS: fsopen fails with ENOSYS、PASS: fspick fails with ENOSYS、PASS: open_tree fails with ENOSYS,随后命中 STARRY_GROUPED_TESTS_PASSED。
CI 状态:当前远端 Detect changed paths、Cancel stale CI runs、Run sync-lint / run_container 已通过,若干互斥/发布 job 为 skipped,Check formatting / run_host 仍 queued。本 PR 的新增 Starry grouped subcase 没有被远端检查完整覆盖,本轮已用上述本地 QEMU flow 补足。
重复/重叠分析:base 文档已有相同修复方向说明,但 origin/dev 代码仍把这三个 syscall 放在 sys_dummy_fd 路径;开放 PR 搜索没有发现其它 fsopen / fspick / open_tree / mount API / sys_dummy_fd 的等价实现或冲突 PR。
4fc0b26 to
43d92ca
Compare
There was a problem hiding this comment.
审查总结
变更范围:3 个文件,+91/−5,改动清晰聚焦。
内核修复(os/StarryOS/kernel/src/syscall/mod.rs):
- 将
fsopen/fspick/open_tree从sys_dummy_fd(返回假 fd)中移出,改为直接返回Err(AxError::Unsupported)(用户态映射为ENOSYS)。 userfaultfd/memfd_secret保留在sys_dummy_fd组,不受影响。- 注释清楚解释了 systemd fallback 语义:新 mount API 入口返回假 fd → systemd 误判能力 → 进入 fsconfig 路径 → 硬失败且不回退。返回 ENOSYS 后 systemd 可正确回退到已支持的经典
mount(2)。 AxError::Unsupported → LinuxError::ENOSYS映射已确认(components/axerrno/src/lib.rs:260)。
回归测试(test-suit/starryos/qemu-smp1/system/bugfix-bug-mount-api-enosys/):
- C 测试通过 raw
syscall()调用 fsopen(430) / fspick(433) / open_tree(428),断言返回 −1 且errno == ENOSYS。 CMakeLists.txt安装到usr/bin/starry-test-suit,与 Starry grouped case 自动发现路径一致。- 修复前测试必定 FAIL(返回假 fd ≥ 0),修复后 PASS,回归钉住有效。
CI 状态:
Detect changed paths/Run sync-lint/Cancel stale CI runs:✅ 通过- 测试类 job(arceos/starry/axvisor 多架构):skipped(路径过滤,本 PR 仅改 syscall dispatch 和新增 test case)
Check formatting / run_host:queued(runner 可用性,非失败)- 无 CI 失败。
重复/重叠分析:扫描了当前所有 open PR,未发现修改 fsopen / fspick / open_tree / sys_dummy_fd 或 mount API 相关代码的冲突 PR。
已有 review:
- mai-team-app[bot]:APPROVED(详细审查)
- ZR233(MEMBER):APPROVED(本地 QEMU 实测验证通过)
无阻塞问题,代码正确、测试完整、注释清晰,建议合并。
Powered by mimo-v2.5-pro
`fsopen`/`fspick`/`open_tree` returned a dummy fd via `sys_dummy_fd`, falsely signalling that the new mount API is available. systemd then proceeds to `fsconfig` on that fd, which is unimplemented and fails, and — because the entry point "succeeded" — it never falls back to the classic `mount(2)`. The result was a hard "Failed to mount cgroup hierarchy" abort. 让这三个 syscall 返回 ENOSYS。systemd 检测到新挂载 API 不可用后会回退到 经典 `mount(2)`(StarryOS 已支持 tmpfs/cgroup2 等)。
43d92ca to
b3cbb13
Compare
There was a problem hiding this comment.
审查总结
变更范围:3 个文件,+91/−5,改动聚焦清晰。
内核修复(os/StarryOS/kernel/src/syscall/mod.rs)
- 将
fsopen/fspick/open_tree从sys_dummy_fd(返回假 fd)中移出,改为直接返回Err(AxError::Unsupported),用户态映射为-ENOSYS。 userfaultfd/memfd_secret保留在sys_dummy_fd组,不受影响。AxError::Unsupported → LinuxError::ENOSYS映射已确认(components/axerrno/src/lib.rs:260)。fsconfig/fsmount/move_mount本就落入默认分支返回 ENOSYS,修复后所有新 mount API 入口行为一致。- 注释完整解释了 systemd fallback 语义:假 fd → systemd 误判能力 → 进入 fsconfig 路径 → 硬失败不回退。与
sys_dummy_fd中对 qemu 进程的"诚实"策略一致。
回归测试(test-suit/starryos/qemu-smp1/system/bugfix-bug-mount-api-enosys/)
- C 测试通过 raw
syscall()直接调用 fsopen(430) / fspick(433) / open_tree(428),断言返回-1且errno == ENOSYS。 CMakeLists.txt安装到usr/bin/starry-test-suit,与 Starry grouped case 自动发现路径一致,会被所有架构(x86_64/aarch64/riscv64/loongarch64)的 system runner 自动执行。- 修复前测试必定 FAIL(返回假 fd ≥ 0),修复后 PASS,回归钉住有效。
- 使用
_GNU_SOURCE+#ifndef回退定义,兼容各架构头文件差异。
本地验证
cargo fmt --check:✅ 通过git diff --check origin/dev...HEAD:✅ 无空白问题git merge-tree origin/dev HEAD:✅ 无冲突
CI 状态
Detect changed paths/Run sync-lint/Cancel stale CI runs:✅ 通过- 测试类 job(arceos/starry/axvisor 多架构):skipped(路径过滤,本 PR 仅改 syscall dispatch 和新增 test case)
- 无 CI 失败
重复/重叠分析
扫描当前所有 open PR,未发现修改 fsopen / fspick / open_tree / sys_dummy_fd 或 mount API 相关代码的冲突 PR。
已有 review
- mai-team-app[bot]:APPROVED ×2
- ZR233(MEMBER):APPROVED(本地 QEMU 实测验证通过)
无阻塞问题,代码正确、测试完整、注释清晰,建议合并。
Powered by mimo-v2.5-pro
…-os#1241) `fsopen`/`fspick`/`open_tree` returned a dummy fd via `sys_dummy_fd`, falsely signalling that the new mount API is available. systemd then proceeds to `fsconfig` on that fd, which is unimplemented and fails, and — because the entry point "succeeded" — it never falls back to the classic `mount(2)`. The result was a hard "Failed to mount cgroup hierarchy" abort. 让这三个 syscall 返回 ENOSYS。systemd 检测到新挂载 API 不可用后会回退到 经典 `mount(2)`(StarryOS 已支持 tmpfs/cgroup2 等)。
…-os#1241) `fsopen`/`fspick`/`open_tree` returned a dummy fd via `sys_dummy_fd`, falsely signalling that the new mount API is available. systemd then proceeds to `fsconfig` on that fd, which is unimplemented and fails, and — because the entry point "succeeded" — it never falls back to the classic `mount(2)`. The result was a hard "Failed to mount cgroup hierarchy" abort. 让这三个 syscall 返回 ENOSYS。systemd 检测到新挂载 API 不可用后会回退到 经典 `mount(2)`(StarryOS 已支持 tmpfs/cgroup2 等)。
`fsopen`/`fspick`/`open_tree` returned a dummy fd via `sys_dummy_fd`, falsely signalling that the new mount API is available. systemd then proceeds to `fsconfig` on that fd, which is unimplemented and fails, and — because the entry point "succeeded" — it never falls back to the classic `mount(2)`. The result was a hard "Failed to mount cgroup hierarchy" abort. 让这三个 syscall 返回 ENOSYS。systemd 检测到新挂载 API 不可用后会回退到 经典 `mount(2)`(StarryOS 已支持 tmpfs/cgroup2 等)。
背景
在 StarryOS 上以 Debian trixie 的 systemd 作为 PID 1 启动时,首次 boot 暴露了若干内核问题。本 PR 修复其中之一:新挂载 API 的桩实现误导了 systemd 的能力探测,使其无法回退到经典
mount(2)。现象
systemd 在早期挂载 cgroup 层级时直接失败并退出(PID 1 退出 → 内核 panic):
根因
fsopen/fspick/open_tree经sys_dummy_fd返回一个假 fd(表示成功)。于是 systemd 认为内核支持新挂载 API(fsopen → fsconfig → fsmount → move_mount),继续调用未实现的fsconfig并失败;又因为入口fsopen"成功"了,systemd 不会回退到经典mount(2)——而后者 StarryOS 是支持的。sys_dummy_fd本身已对 qemu 进程特判返回Unsupported(注释写明"要对 qemu 诚实,它会自动 fallback"),systemd 同理,只是没有被诚实对待。修复
让
fsopen/fspick/open_tree返回AxError::Unsupported(映射为ENOSYS)。systemd 检测到新挂载 API 不可用后即回退到经典mount(2)。fsconfig/fsmount/move_mount本就落到默认分支返回 ENOSYS,行为现在一致。测试
新增回归用例
qemu-smp1/system/bugfix-bug-mount-api-enosys:断言fsopen/fspick/open_tree均返回-1且errno == ENOSYS。修复前返回 dummy fd(≥ 0)会 FAIL,从而钉住该行为。