Repository navigation
fix(sandbox): retry a Retained unmount through the workspace record's token (#538) - #653
Open
mengmengmengqiang wants to merge 1 commit into
Conversation
… token (Ephemeral-AI-Lab#538) workspace.unmount re-sent a retryable Retained detach by calling state.token(path), which re-runs unmount_guard::check and re-reports the Retained custody before the retry reaches the daemon. Read the WorkspaceToken from the workspace record (files::token_of, as sandbox.close does) instead, so a later unmount actually re-attempts the recorded EBUSY detach once the holder is gone.
mengmengmengqiang
force-pushed
the
fix/538-unmount-retry
branch
from
November 12, 2026 04:13
0283524 to
46109ee
Compare
mengmengmengqiang
force-pushed
the
fix/538-custody-retry
branch
from
November 12, 2026 04:13
e64ed57 to
4020e90
Compare
mengmengmengqiang
requested review from
jiangkoumo and
yifanxuaaa
and removed request for
yifanxuaaa
November 12, 2026 05:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
workspace.unmountre-sent a retryable Retained detach by callingstate.token(path), which re-runsunmount_guard::checkand re-reports theRetained custody before the retry reaches the daemon. A user who retried the
unmount after the holder exited kept getting the same Retained answer.
This branch reads the
WorkspaceTokenfrom the workspace record(
files::token_of, exactly assandbox.closealready does) instead, so a laterunmount actually re-attempts the recorded
EBUSYdetach once the holder is gone.What it fixes
workspace.unmounton a Retained Workspace retries the recorded detach insteadof short-circuiting on the guard's custody report (Unmount: force while a foreground exec orphan holds the mount leaves Retained(Detach), and later unmount/force/close cannot recover #538).
unmount_guard::token(state, path)— the single path→token mapper over theworkspace record — is now
pub.files::token_ofis nowpubso that mapper reuses it instead of a seconddecoder.
Files:
control/crates/layerfs-sandbox/src/{files,unmount_guard,workspace/serve}.rs.Stack
fix/538-custody-retry@4020e9097(baselayerfs_v2_0_0@03883a63c) — Retained custody andsandbox.destroy.fix/538-unmount-retry@46109ee56→ basefix/538-custody-retry— the unmount path.fix/538-close-refuse@995627e09→ basefix/538-unmount-retry— thesandbox.closepath.Rebased onto the current base on 2026-11-12:
layerfs_v2_0_0moved from thestack's fork point
833d04cf4to03883a63c(#639/#641/#621/#543/#547/#655).No commits were squashed and authorship is unchanged.
Test evidence — Dell (aluminium), Linux x86_64, cargo 1.85.1
Rebased stack, verified at the stack head
995627e09(Linuxx86_64, 88 cores,/dev/fusepresent ascrw-rw-rw-). Non-mount test binaries ran as the ordinaryuser; the four Linux-only FUSE mount targets (the repo's own
tools/ci_tests.pymount lane) ran as root with
/dev/fuse, underflock /tmp/dell-fuse.lock./dev/fusewas left at666. Logs:/home/dell/538-538v2-*.log.Gates (all exit 0):
cargo +1.85.1 fmt --all -- --checkcargo +1.85.1 clippy --locked --workspace --exclude layerfs-node --all-targets -- -D warningscargo +1.85.1 build --locked -p layerfs-daemon(mount-lane prerequisite)cargo +1.85.1 test --locked -p layerfs-sandbox -p layerfs-control -p layerfs-api --no-runTests (
cargo test -p layerfs-sandbox -p layerfs-control -p layerfs-api, eachbuilt test binary run individually):
FUSE mount targets run as root (12 tests, all pass):
kernel_application1,kernel_mount_routes2,observed_application8,r5_1_actual_daemon_commit1.The 4 ignored tests are the repository's own
#[ignore]fixtures, unchanged bythis branch:
remote_store::minio_round_trip(needs MinIO),store_family::a_killed_opener_leaves_its_log_frames,doctor_sandbox::worker_fixture_server,store_doctor::worker_child.Why the earlier CI on this PR was red
clippy:control/crates/layerfs-home/src/home/capacity.rs:8hadu64::from(filesystem.blocks_available()), auseless_conversiononx86_64-linux. The old base
e64ed5743had it;03883a63cwidens throughu128(fix(daemon): reclaim control slots after retained connection failure (#540) #543), so the rebased stack is clean.test:layerfs-store-service::sdk_blame_coarse::lines_between_distant_edits_keep_their_originfailed on the old stack because it branched before fix(content): align store-service line_alignment::exact with the #517 unique-line fallback #639;
03883a63ccarriesfix(content): align store-service line_alignment::exact with the #517 unique-line fallback #639's fix, so it passes.
windows build (reports only)is a pre-existing Windows-only lint,non-gating (
continue-on-error) and unchanged by these branches.CI on the rebased head
cirun 43154286536,attempt 3 (head
46109ee56):fmt and guardspass,clippypass,testpass,windows build (reports only)fail (pre-existing, non-gating). The first twoattempts failed on two different pre-existing concurrency tests —
layerfs-control::doctor_host::concurrent_management_record_rewrites_leave_consistency_incompleteand
layerfs-persistence::concurrent_first_installs::two_writers_saving_the_same_new_content_both_complete(
Err(Integrity("dependency cycle"))). Neither crate is touched by this stack;both tests pass on Dell (full suite three times, plus 25 repeats pinned to four
CPUs with
taskset -c 0-3).NOT RUN
--workspace) — only the three packages named inthe task were run.
layerfs-daemonpackage tests, including the Linux-onlystalled_unmountmount target — outside the three requested packages; thedaemon binary was built only as the mount-lane prerequisite.
tools/ci_tests.py nightly) — not requested.cargo check/fmt/clippyand one sandbox-package smoke run passed, reported as compile-only.
No merges; #538, #547 and #640 stay open.
Refs #538, #547, #640.