blob: 1c39471ebf0c7e02c698fc0919c0e8eb21990654 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
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<File> {
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)
}
|