Unmount: force while a foreground exec orphan holds the mount leaves Retained(Detach), and later unmount/force/close cannot recover

オープン
#538 コメント 3 件 リアクション 0 件 担当者 1 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@mengmengmengqiang がすでに取り組んでいます。

2026年11月8日 から。

  • #640 @mengmengmengqiang による — オープン
  • #653 @mengmengmengqiang による — オープン
  • #654 @mengmengmengqiang による — オープン

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
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 の本文から書いたものです。

説明

bug question

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: client SIGKILL during foreground exec → Busy → force → Retained(Detach) → no recovery

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

  1. sandbox.create(), workspace.mount(sandbox, "lane").
  2. Start a foreground workspace.exec(ws, "sleep 20") (the command's cwd is the mount), then SIGKILL the client process that owns the exec.
  3. workspace.unmount(ws) → Busy (phase: unmount:kernel); unmount(ws, true) (discard) → Busy.
  4. 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 })
  })
}
  1. Wait 30 s (the sleep 20 orphan has exited). Six normal unmounts all return the same Retained(stage: Detach, detached: false); a second force also fails; sandbox.close("1") returns MountsActive with workspaces: ["/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 force while 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分
マージ済み PR(30日)
138

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Ephemeral-AI-Lab/layerfs のほかの issue

Ephemeral-AI-Lab/layerfs の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。