Skip to content

Commit 47b033e

Browse files
authored
Rollup merge of rust-lang#107086 - clubby789:bootstrap-lock-pid-linux, r=albertlarsan68
Print PID holding bootstrap build lock on Linux Partially address rust-lang#107077 Parse `/proc/locks` to find the PID of the process which created the build directory lock
2 parents 00a8e59 + 9806a9e commit 47b033e

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/bootstrap/bin/main.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//! directory in each respective module.
77
88
use std::env;
9+
use std::fs::File;
10+
use std::io::{BufRead, BufReader};
911

1012
use bootstrap::{t, Build, Config, Subcommand, VERSION};
1113

@@ -16,12 +18,17 @@ fn main() {
1618
let mut build_lock;
1719
let _build_lock_guard;
1820
if cfg!(any(unix, windows)) {
19-
build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(config.out.join("lock"))));
21+
let path = config.out.join("lock");
22+
build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(&path)));
2023
_build_lock_guard = match build_lock.try_write() {
2124
Ok(lock) => lock,
2225
err => {
23-
println!("warning: build directory locked, waiting for lock");
2426
drop(err);
27+
if let Some(pid) = get_lock_owner(&path) {
28+
println!("warning: build directory locked by process {pid}, waiting for lock");
29+
} else {
30+
println!("warning: build directory locked, waiting for lock");
31+
}
2532
t!(build_lock.write())
2633
}
2734
};
@@ -98,3 +105,27 @@ fn check_version(config: &Config) -> Option<String> {
98105

99106
Some(msg)
100107
}
108+
109+
/// Get the PID of the process which took the write lock by
110+
/// parsing `/proc/locks`.
111+
#[cfg(target_os = "linux")]
112+
fn get_lock_owner(f: &std::path::Path) -> Option<u64> {
113+
use std::os::unix::fs::MetadataExt;
114+
let lock_inode = std::fs::metadata(f).ok()?.ino();
115+
let lockfile = File::open("/proc/locks").ok()?;
116+
BufReader::new(lockfile).lines().find_map(|line| {
117+
// pid--vvvvvv vvvvvvv--- inode
118+
// 21: FLOCK ADVISORY WRITE 359238 08:02:3719774 0 EOF
119+
let line = line.ok()?;
120+
let parts = line.split_whitespace().collect::<Vec<_>>();
121+
let (pid, inode) = (parts[4].parse::<u64>().ok()?, &parts[5]);
122+
let inode = inode.rsplit_once(':')?.1.parse::<u64>().ok()?;
123+
if inode == lock_inode { Some(pid) } else { None }
124+
})
125+
}
126+
127+
#[cfg(not(target_os = "linux"))]
128+
fn get_lock_owner(f: &std::path::Path) -> Option<u64> {
129+
// FIXME: Implement on other OS's
130+
None
131+
}

0 commit comments

Comments
 (0)