about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-01-26 06:15:25 +0100
committerGitHub <noreply@github.com>2023-01-26 06:15:25 +0100
commit4b51b20d8710f7e543be02ac9ef6f65842c1926a (patch)
tree5bb279ae8ae3e323c22dcff9ab27591b269610c3
parentf3644ca64de6357a07a3901dd2dacbda247beec6 (diff)
parent72117ab2c7c32805e963bbf5f0d1bdc7cd72274c (diff)
downloadrust-4b51b20d8710f7e543be02ac9ef6f65842c1926a.tar.gz
rust-4b51b20d8710f7e543be02ac9ef6f65842c1926a.zip
Rollup merge of #107086 - clubby789:bootstrap-lock-pid-linux, r=albertlarsan68
Print PID holding bootstrap build lock on Linux

Partially address #107077

Parse `/proc/locks` to find the PID of the process which created the build directory lock
-rw-r--r--src/bootstrap/bin/main.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index be69f819c64..3856bb64fb3 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -16,12 +16,17 @@ fn main() {
     let mut build_lock;
     let _build_lock_guard;
     if cfg!(any(unix, windows)) {
-        build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(config.out.join("lock"))));
+        let path = config.out.join("lock");
+        build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(&path)));
         _build_lock_guard = match build_lock.try_write() {
             Ok(lock) => lock,
             err => {
-                println!("warning: build directory locked, waiting for lock");
                 drop(err);
+                if let Some(pid) = get_lock_owner(&path) {
+                    println!("warning: build directory locked by process {pid}, waiting for lock");
+                } else {
+                    println!("warning: build directory locked, waiting for lock");
+                }
                 t!(build_lock.write())
             }
         };
@@ -98,3 +103,30 @@ fn check_version(config: &Config) -> Option<String> {
 
     Some(msg)
 }
+
+/// Get the PID of the process which took the write lock by
+/// parsing `/proc/locks`.
+#[cfg(target_os = "linux")]
+fn get_lock_owner(f: &std::path::Path) -> Option<u64> {
+    use std::fs::File;
+    use std::io::{BufRead, BufReader};
+    use std::os::unix::fs::MetadataExt;
+
+    let lock_inode = std::fs::metadata(f).ok()?.ino();
+    let lockfile = File::open("/proc/locks").ok()?;
+    BufReader::new(lockfile).lines().find_map(|line| {
+        //                       pid--vvvvvv       vvvvvvv--- inode
+        // 21: FLOCK  ADVISORY  WRITE 359238 08:02:3719774 0 EOF
+        let line = line.ok()?;
+        let parts = line.split_whitespace().collect::<Vec<_>>();
+        let (pid, inode) = (parts[4].parse::<u64>().ok()?, &parts[5]);
+        let inode = inode.rsplit_once(':')?.1.parse::<u64>().ok()?;
+        if inode == lock_inode { Some(pid) } else { None }
+    })
+}
+
+#[cfg(not(target_os = "linux"))]
+fn get_lock_owner(_: &std::path::Path) -> Option<u64> {
+    // FIXME: Implement on other OS's
+    None
+}