Unmount: force while a foreground exec orphan holds the mount leaves Retained(Detach), and later unmount/force/close cannot recover
维护者通常 1 天内回复
@mengmengmengqiang 已经在做这个了。
开始于 2026年11月8日。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 14/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- rust
调研方向
No file is named; the entry points are the workspace.unmount force path and sandbox.close, which return Retained(TeardownCustody { stage: Detach }) with detach Failed(EBUSY). Start by reproducing the four steps on the stated kernel and reading the code that builds ForcedFacts and the MountWork snapshot, then compare it with the no-force control path that recovers at the #497 join grace. There is no agreed outcome yet — the issue offers two options (retry detach once the holder is gone, or refuse force while a holder exists) — so the first deliverable is a decision on which, plus the /458 docs note; only then is there a patch to write.
由索引模型根据 Issue 内容生成。
描述
A forced unmount while a foreground workspace.exec orphan still holds the mount returns Retained(TeardownCustody { stage: Detach, detached: false, ... }), and from then on normal unmounts, another force, and sandbox.close all keep failing — even after the orphan command has exited. This came out of verifying #458; the clean path (no force) recovers normally.

Sequence: the client dies during a foreground exec; unmount and discard return Busy; force returns Retained(Detach); after the orphan exits, later unmounts and a second force still return Retained, and close stays MountsActive. The green control has no early force and recovers.
Environment: macOS 26.5.1, OrbStack 7.2.9, kernel 7.2.9-orbstack-00391, Docker 29.8.2; LayerFS 9a03429a (#496/#497 present), real Sandbox.
Steps
sandbox.create(),workspace.mount(sandbox, "lane").- Start a foreground
workspace.exec(ws, "sleep 20")(the command's cwd is the mount), then SIGKILL the client process that owns the exec. workspace.unmount(ws)→Busy(phase: unmount:kernel);unmount(ws, true)(discard) →Busy.- While the orphan is alive,
workspace.unmount(ws, true, true)(force) →
Failed: OperationFailure {
request: ForceUnmount { ..., relinquish_unknown: false },
cause: Retained(TeardownCustody {
stage: Detach, detached: false,
work: Some(MountWork { loops_configured: 2, loops_entered: 2, loops_exited: 2, loops_joined: 2, active: 0, retained: 0, ... }),
detail: "forced drain stopped at Detach: detach Failed(EBUSY), loops Some(SessionSnapshot { phase: Joined, ... }), work Some(MountWork { active: 0, retained: 0, requests: 5, completed: 5, terminal: true })",
forced: Some(ForcedFacts { abort: Written, detach: Busy, commit: Absent, fenced: 0 })
})
}
- Wait 30 s (the
sleep 20orphan has exited). Six normal unmounts all return the sameRetained(stage: Detach, detached: false); a secondforcealso fails;sandbox.close("1")returnsMountsActivewithworkspaces: ["/workspaces/1"].
Control
Without the early force: unmount retries at 5/10/15 s are Busy; at ~20 s (after sleep 20 exits) the normal unmount returns Unmounted (1033 ms, the #497 grace), and sandbox.close returns Closed (375 ms).
Question
Is the post-force state intended to be unrecoverable? The orphan's cwd/descriptor was still alive when the detach failed (EBUSY), so Retained(Detach) is a reasonable custody record; but once the holder is gone, there is no SDK path to retry the detach from that record. Options:
- make a later unmount (or a second force) re-attempt the detach once the holder is gone, or
- refuse
forcewhile a cwd/descriptor holder exists and say the caller must kill/wait first, and document that state.
At minimum, the /458 docs answer should mention that force can leave Retained(Detach) and that the workspace then cannot be unmounted or its Sandbox closed. No code change is claimed here; this is a diagnostic report with the exact custody.
Related: #458 (foreground exec client death leaves the command running and the mount Busy), #422 (Workspace/container leak), #497 (join grace, not involved in the failed force detach).
- 主要语言
- Rust
- 星标
- 2.1k
- 派生
- 110
- 平均合并
- 23 小时 52 分钟
- 30 天内合并 PR
- 138
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
Ephemeral-AI-Lab/layerfs 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
Ephemeral-AI-Lab/layerfs#689 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
Ephemeral-AI-Lab/layerfs#643 ·
维护者通常 1 天内回复
-
`branch.publish` accepts a stale base and overwrites `main` (lost update)可能已有人在做 @mengmengmengqiang 今天认领。 未关闭api/calls bug core/history
Ephemeral-AI-Lab/layerfs#691 · 1 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 8/100
Ephemeral-AI-Lab/layerfs#684 · 10 条评论 ·
维护者通常 1 天内回复
-
docs
难度 5/5 一周以上 新手友好度 15/100
Ephemeral-AI-Lab/layerfs#683 ·
维护者通常 1 天内回复
查看 Ephemeral-AI-Lab/layerfs 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
-
难度 2/5 1-3 小时 新手友好度 65/100
pop-os/cosmic-settings#2296 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
jonathanong/no-mistakes#3431 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
Eyevinn/open-live-ingest#36 · 1 条评论 ·
维护者通常 1 天内回复