fix(hardlink): name the mutable set directly, under both build-dir layouts
CI / shellcheck + selftests (pull_request) Skipped
CI / shellcheck + selftests (pull_request) Skipped
`unshare_mutable_paths` selected `.fingerprint` and `build` directories. Under Cargo's build-dir layout v2 the first clause matches nothing and the second matches the whole tree, because v2 regroups artifacts under `build/` alongside the metadata. Measured on one scratch crate: 39.3% of the tree real-copied under v1, 99.996% under v2. The selection now names the mutable set rather than the container it used to live in: fingerprint directories under either spelling, layout v2's `run/` directories, layout v1's loose build-script run metadata, and the `out` directories that are a build script's OUT_DIR rather than a compile unit's artifact directory. The two are told apart structurally, by Cargo's record of the build-script execution sitting beside the OUT_DIR and nowhere else. Verifying that turned up a second, layout-independent hazard: a linked executable is written through whatever inode is already at its path, so a `cargo test --no-run` inside a `cp -al` clone rewrites the source's own test binary. Reproduced on cargo 1.93.1 stable, 1.96.0-nightly, 1.98.0-nightly and 1.100.0-nightly, under both layouts. Every executable is now real-copied; `.rlib`, `.rmeta` and `incremental/` are what stay shared. hardlink-clone-selftest.sh gains two file-only layout fixtures that pin the partition in both directions without a compiler, and a live scenario that relinks a test binary.
This commit is contained in:
@@ -53,9 +53,11 @@ pass_count=0
|
||||
fail() { echo "ASSERTION FAILED: $*" >&2; exit 1; }
|
||||
ok() { pass_count=$((pass_count + 1)); echo "PASS: $*"; }
|
||||
|
||||
# Cargo and rustc REPLACE an artifact (write elsewhere, rename over the path)
|
||||
# rustc REPLACES an `.rlib`/`.rmeta` (writes elsewhere, renames over the path)
|
||||
# rather than truncating it in place, which is exactly why a snapshot may
|
||||
# share artifact inodes with the live target dir it was cloned from. The
|
||||
# share those inodes with the live target dir it was cloned from. Linker
|
||||
# outputs are the exception and are real-copied instead — see
|
||||
# `unshare_mutable_paths` in cache-lib.sh. The
|
||||
# fixtures here have to model that faithfully — a plain `>` redirect truncates
|
||||
# in place and would write straight through the shared inode into the
|
||||
# snapshot and every consumer, which is a property of the test fixture, not of
|
||||
|
||||
Reference in New Issue
Block a user