use anyhow::{Context, Result, ensure}; use std::{ fs::{File, OpenOptions}, os::fd::AsRawFd, os::unix::fs::{MetadataExt, OpenOptionsExt}, path::Path, }; pub fn controller_lock() -> Result { let directory = Path::new("/run/roentgen"); std::fs::create_dir_all(directory)?; let metadata = std::fs::symlink_metadata(directory)?; ensure!( metadata.is_dir() && metadata.uid() == unsafe { libc::geteuid() } && metadata.mode() & 0o022 == 0, "Runtime directory must be service-owned and not writable by other users" ); let file = OpenOptions::new() .create(true) .truncate(false) .read(true) .write(true) .mode(0o600) .custom_flags(libc::O_NOFOLLOW) .open(directory.join("controller.lock")) .context("Open controller lock")?; // SAFETY: file owns this live fd; flock does not retain a pointer. let result = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }; ensure!( result == 0, "Another controller is running; stop it before explicit recovery" ); Ok(file) }