From ffdc40f30ab3ed1b4b1b7e5b2c877f21fe4e38ef Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 14 Aug 2025 17:51:48 -0700 Subject: [PATCH 1/2] bootstrap: Switch from fd-lock to native locking in std In the process, fix a race condition, by never truncating or writing to the file unless we currently hold the lock. --- src/bootstrap/Cargo.lock | 12 --------- src/bootstrap/Cargo.toml | 1 - src/bootstrap/src/bin/main.rs | 46 ++++++++++++++++------------------- 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 537f4b6184f1b..e5f95b8727317 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -48,7 +48,6 @@ dependencies = [ "clap", "clap_complete", "cmake", - "fd-lock", "home", "ignore", "insta", @@ -268,17 +267,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fd-lock" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" -dependencies = [ - "cfg-if", - "rustix", - "windows-sys 0.59.0", -] - [[package]] name = "filetime" version = "0.2.25" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index bdf0b42255ee5..60c3548e16de4 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -38,7 +38,6 @@ cmake = "=0.1.54" build_helper = { path = "../build_helper" } clap = { version = "4.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] } clap_complete = "4.4" -fd-lock = "4.0" home = "0.5" ignore = "0.4" libc = "0.2" diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 8b2d67266a77b..93c7faf4f0159 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -5,8 +5,8 @@ //! parent directory, and otherwise documentation can be found throughout the `build` //! directory in each respective module. -use std::fs::{self, OpenOptions}; -use std::io::{self, BufRead, BufReader, IsTerminal, Write}; +use std::fs::{self, OpenOptions, TryLockError}; +use std::io::{self, BufRead, BufReader, IsTerminal, Read, Write}; use std::path::Path; use std::str::FromStr; use std::time::Instant; @@ -39,38 +39,34 @@ fn main() { let config = Config::parse(flags); let mut build_lock; - let _build_lock_guard; if !config.bypass_bootstrap_lock { // Display PID of process holding the lock // PID will be stored in a lock file let lock_path = config.out.join("lock"); - let pid = fs::read_to_string(&lock_path); - - build_lock = fd_lock::RwLock::new(t!(fs::OpenOptions::new() + build_lock = t!(fs::OpenOptions::new() + .read(true) .write(true) - .truncate(true) .create(true) - .open(&lock_path))); - _build_lock_guard = match build_lock.try_write() { - Ok(mut lock) => { - t!(lock.write(process::id().to_string().as_ref())); - lock + .truncate(false) + .open(&lock_path)); + t!(build_lock.try_lock().or_else(|e| { + if let TryLockError::Error(e) = e { + return Err(e); } - err => { - drop(err); - // #135972: We can reach this point when the lock has been taken, - // but the locker has not yet written its PID to the file - if let Some(pid) = pid.ok().filter(|pid| !pid.is_empty()) { - println!("WARNING: build directory locked by process {pid}, waiting for lock"); - } else { - println!("WARNING: build directory locked, waiting for lock"); - } - let mut lock = t!(build_lock.write()); - t!(lock.write(process::id().to_string().as_ref())); - lock + let mut pid = String::new(); + t!(build_lock.read_to_string(&mut pid)); + // #135972: We can reach this point when the lock has been taken, + // but the locker has not yet written its PID to the file + if !pid.is_empty() { + println!("WARNING: build directory locked by process {pid}, waiting for lock"); + } else { + println!("WARNING: build directory locked, waiting for lock"); } - }; + build_lock.lock() + })); + t!(build_lock.set_len(0)); + t!(build_lock.write_all(process::id().to_string().as_bytes())); } // check_version warnings are not printed during setup, or during CI From 56b33cd5fa0eb2814f94f5fc636775ac70d10b0e Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 14 Aug 2025 18:02:39 -0700 Subject: [PATCH 2/2] bootstrap: Remove dependency on xattr Extracting the Rust tarballs doesn't require this. --- src/bootstrap/Cargo.lock | 15 ++------------- src/bootstrap/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index e5f95b8727317..be29e77e572af 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -747,13 +747,12 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", - "xattr", ] [[package]] @@ -1135,16 +1134,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "xattr" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" -dependencies = [ - "libc", - "rustix", -] - [[package]] name = "xz2" version = "0.1.7" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 60c3548e16de4..cd5a60187e51b 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -50,7 +50,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" sha2 = "0.10" -tar = "0.4" +tar = { version = "0.4.44", default-features = false } termcolor = "1.4" toml = "0.5" walkdir = "2.4"