Repository navigation
ghc: retry hadrian once on the stamp-file lock race (GHC #24365) - #1357
bryan-minimal wants to merge 1 commit into
Conversation
Parallel hadrian intermittently fails on a stamp file it is writing itself
("stamp-os-string-2.0.7-inplace_dyn: withFile: resource busy (file is
locked)", amd64, pkgs#1351 world build). Upstream GHC #24365, still open.
Run both hadrian invocations through run_hadrian, which tees the output to
a log and retries exactly once when that log contains "resource busy (file
is locked)". Any other failure, or the lock error twice, fails as before.
Shake resumes from .shake.database, so completed rules are not rerun and
flags and outputs are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
In the pkgs#1351 (zlib 1.4) world build, ghc failed in stage1 on amd64 with no compile or link error:
The same build passed on arm64. This is a known intermittent hadrian race. It appears when hadrian runs in parallel, and we have built that way since #575 (
-j$(nproc)). Upstream tracks it as GHC #24365, "Intermittent hadrian exception: withFile: resource busy (file is locked)" (https://gitlab.haskell.org/ghc/ghc/-/issues/24365). That issue reports the samestamp-<pkg>-inplace_dynfiles failing on Linux and Darwin CI. It is still open and no GHC release fixes it, so moving to a newer GHC would not help. GHC #24382 (https://gitlab.haskell.org/ghc/ghc/-/issues/24382) covers a Windows variant from copyFile. GHC #20886 notes thatwithFilecan put the wrong file name on an exception, so the stamp name might be misleading, but the failure is transient either way.Change
Both hadrian invocations now go through a small
run_hadrianhelper in packages/ghc/build.sh. It tees hadrian's output tohadrian-<phase>.attempt<N>.lognext to_build. If the first attempt fails and that log containsresource busy (file is locked), the helper prints "hadrian (): transient stamp-file lock race; retrying once (Shake resumes)" and runs hadrian again. Every other case fails as it did before: a different error, or the lock error a second time, returns hadrian's exit code with no retry.The install invocation goes through the same helper because
hadrian installre-checks the whole build graph under the same-jbefore copying, so it can hit the same race.HADRIAN_FLAGSnow gets passed inside the helper, which means the build and the install still use identical flags, as #575 requires.Reproducibility
Flags, the flavour and the install prefix are unchanged, and nothing new is written to
$OUTPUT_DIR. A resumed build produces the same bytes. Shake loads.shake.databaseand skips every rule that already completed, so those outputs stay on disk untouched. It reruns only the rules that did not finish, with the same commands and flags. The two #277 patches are applied to the source before hadrian runs, so they are unaffected.Verification
bash -n packages/ghc/build.shpasses.HADRIAN_FLAGSthr 8000 ough the install line) against a stubbed_build/bin/hadrian:DESTDIRreaches both install calls.Rebuild scope
The ghc spec changes, so these rebuild:
That is 6 packages in total, all Haskell. ghc has
build_cost_multiple = 6, so this is best landed alongside a world rebuild rather than on its own.🤖 Generated with Claude Code
Summary by CodeRabbit