Skip to content

fix(starry): report ENOSYS for the unimplemented new mount API#1241

Merged
ZR233 merged 1 commit into
rcore-os:devfrom
programskillforverification:systemd/fix-mount-api-enosys
Jun 16, 2026
Merged

fix(starry): report ENOSYS for the unimplemented new mount API#1241
ZR233 merged 1 commit into
rcore-os:devfrom
programskillforverification:systemd/fix-mount-api-enosys

Conversation

@programskillforverification

Copy link
Copy Markdown
Contributor

背景

在 StarryOS 上以 Debian trixie 的 systemd 作为 PID 1 启动时,首次 boot 暴露了若干内核问题。本 PR 修复其中之一:新挂载 API 的桩实现误导了 systemd 的能力探测,使其无法回退到经典 mount(2)

现象

systemd 在早期挂载 cgroup 层级时直接失败并退出(PID 1 退出 → 内核 panic):

Dummy fd created: fsopen
Unimplemented syscall: fsconfig (tid=1)
Failed to mount tmpfs (type tmpfs) on /sys/fs/cgroup (...): No such file or directory
[!!!!!!] Failed to mount cgroup v1 hierarchy.
Exiting PID 1...

根因

fsopen / fspick / open_treesys_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 均返回 -1errno == ENOSYS。修复前返回 dummy fd(≥ 0)会 FAIL,从而钉住该行为。

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

变更内容:将 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::ENOSYShandle_syscallunwrap_or_else 正确将错误转换为 -ENOSYS 返回用户态。修改正确且完整。
  • 注释清晰解释了 systemd fallback 语义和为什么不能返回假 fd。
  • fsconfig / fsmount / move_mount 本就落入默认分支返回 ENOSYS,行为现在一致。

测试验证

  • 新增 C 回归测试通过 raw syscall() 直接调用 fsopen/fspick/open_tree,断言返回 -1errno == 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 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复查当前 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() 直接断言 fsopenfspickopen_tree 返回 -1errno == 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/system grouped 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 ENOSYSPASS: fspick fails with ENOSYSPASS: open_tree fails with ENOSYS,随后命中 STARRY_GROUPED_TESTS_PASSED

CI 状态:当前远端 Detect changed pathsCancel stale CI runsRun 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。

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

变更范围:3 个文件,+91/−5,改动清晰聚焦。

内核修复os/StarryOS/kernel/src/syscall/mod.rs):

  • fsopen / fspick / open_treesys_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 等)。
@ZR233
ZR233 force-pushed the systemd/fix-mount-api-enosys branch from 43d92ca to b3cbb13 Compare June 16, 2026 08:47

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

变更范围:3 个文件,+91/−5,改动聚焦清晰。

内核修复(os/StarryOS/kernel/src/syscall/mod.rs

  • fsopen / fspick / open_treesys_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),断言返回 -1errno == 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

@ZR233
ZR233 merged commit 7a8aa51 into rcore-os:dev Jun 16, 2026
89 of 100 checks passed
This was referenced Jun 16, 2026
Antareske pushed a commit to Antareske/tgoskits that referenced this pull request Jun 27, 2026
…-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 等)。
Antareske pushed a commit to Antareske/tgoskits that referenced this pull request Jun 27, 2026
…-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 等)。
luodeb pushed a commit that referenced this pull request Jun 30, 2026
`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 等)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants