Repository navigation
fix(coreutils): give each shim_dir call its own staging dir - #523
Merged
Merged
Conversation
The staging dir was named `.tmp-<pid>-<name>`, so concurrent targets in one heph process that all hit a cold shim dir shared it. One caller's stale-dir `remove_dir_all` raced another's symlink writes and failed with "Directory not empty" (or "File exists" on the symlink). Add a process-wide counter to the name so each call stages alone. The rename into place already loses a race harmlessly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
A cold start of the builtin coreutils shim dir can fail with
Directory not empty. It also happens onmaster.shim_dirstaged into.tmp-<pid>-<name>, a name that is unique per process but not per call. Concurrent targets in one heph all reach a cold shim dir at once and share that dir. One caller's "clear stale staging"remove_dir_allraces another caller's symlink writes.Fix
Add a process-wide
AtomicU64sequence to the staging name:.tmp-<pid>-<seq>-<name>. Each call now stages alone. The publish step (renameinto place, where the loser of a race checks that the winner's dir exists) was already safe and is unchanged.Test
shim_dir_survives_concurrent_cold_start_in_one_process: 16 threads behind a barrier callshim_diron a fresh home, repeated 20 times. Every thread must get a complete shim set.Run against the unfixed code, it fails (same race, sibling symptom):
With the fix it passes, and still passed on 3 reruns.
cargo test -p coreutilsandlintpass.🤖 Generated with Claude Code