summaryrefslogtreecommitdiff
path: root/src/locking.rs
diff options
context:
space:
mode:
authorAndrew Guschin <guschin@altlinux.org>2026-10-30 03:10:41 +0400
committerAndrew Guschin <guschin@altlinux.org>2026-10-30 03:10:41 +0400
commitd608ffeeda1a479c9dc0e5f6ad269ba07a510d7f (patch)
tree3824ec9da5ca0adac913cc47e3e20054c3dc843a /src/locking.rs
parent40cf3276cdc74bf6f1795990ed600891a637d1fe (diff)
Implement Linux proxy controller, subscription state, and CLI/TUI
Diffstat (limited to 'src/locking.rs')
-rw-r--r--src/locking.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/locking.rs b/src/locking.rs
new file mode 100644
index 0000000..1c39471
--- /dev/null
+++ b/src/locking.rs
@@ -0,0 +1,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)
+}