From 4c9c37516454e3d776fc012353e38d3b8d01d087 Mon Sep 17 00:00:00 2001 From: KK Date: Fri, 11 Sep 2026 16:03:48 +0530 Subject: [PATCH 1/2] Fix OverlayBuilder on persistent toolchain dirs When sccache-dist restarts, the in-memory toolchain_dir_map is wiped but the on-disk toolchain directories survive. On the next build, prepare_overlay_dirs hits the else branch (toolchain not in the map) and calls fs::create_dir on the existing directory, which returns an AlreadyExists error and fails the build. Guard create_dir with an exists() check. The archive_id is a content hash, so a pre-existing directory for the same id already holds the correct unpacked toolchain and is safe to reuse. Signed-off-by: KK --- src/bin/sccache-dist/build.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bin/sccache-dist/build.rs b/src/bin/sccache-dist/build.rs index bfd7a980e5..2f3ad2c4b3 100644 --- a/src/bin/sccache-dist/build.rs +++ b/src/bin/sccache-dist/build.rs @@ -190,7 +190,12 @@ impl OverlayBuilder { entry.clone() } else { trace!("Creating toolchain directory for {}", tc.archive_id); - fs::create_dir(&toolchain_dir)?; + // The directory can persist on disk from a previous server + // process (or a toolchain evicted from the in-memory map + // without its directory). Treat it as already-prepared. + if !toolchain_dir.exists() { + fs::create_dir(&toolchain_dir)?; + } let mut tccache = tccache.lock().unwrap(); let toolchain_rdr = match tccache.get(tc) { From b843c029975138cc0ea9c5327623b678df25797b Mon Sep 17 00:00:00 2001 From: KK Date: Fri, 11 Sep 2026 16:03:48 +0530 Subject: [PATCH 2/2] Package rustlib/ not whole sysroot lib dir On distros where rustc --print sysroot reports /usr (e.g. Void Linux), the ToolchainPackager joins LIBS_DIR ("lib") to the sysroot and packages the entire /usr/lib tree. This drags the full system library set (several GiB) into every distributed toolchain archive, blowing past the toolchain cache size and making toolchain packaging prohibitively slow. Package the rustlib/ subtree instead, which is the actual Rust standard library. Fall back to the old behavior (whole lib dir) if rustlib/ does not exist, preserving compatibility with non-standard sysroot layouts. Signed-off-by: KK --- src/compiler/rust.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/compiler/rust.rs b/src/compiler/rust.rs index 779e9dd79e..fd93c2c32d 100644 --- a/src/compiler/rust.rs +++ b/src/compiler/rust.rs @@ -2285,10 +2285,18 @@ impl pkg::ToolchainPackager for RustToolchainPackager { let sysroot_executable = bins_path.join("rustc").with_extension(EXE_EXTENSION); package_builder.add_executable_and_deps(sysroot_executable)?; - package_builder.add_dir_contents(&bins_path)?; + // Package the Rust standard library subtree instead of the entire + // sysroot lib directory. Distros like Void Linux report `/usr` as the + // sysroot, so packaging `$sysroot/lib` would drag in the whole system + // library tree (several GiB) rather than just the Rust stdlib. if BINS_DIR != LIBS_DIR { let libs_path = sysroot.join(LIBS_DIR); - package_builder.add_dir_contents(&libs_path)?; + let rustlib_path = libs_path.join("rustlib"); + if rustlib_path.is_dir() { + package_builder.add_dir_contents(&rustlib_path)?; + } else { + package_builder.add_dir_contents(&libs_path)?; + } } package_builder.into_compressed_tar(f)