summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-10-26 17:03:07 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-10-26 17:03:07 +0200
commit61746b64b0e7087b17b21df6a1c7291ad25cd428 (patch)
tree5db7fd11bd116a61ed9df1ba3d94226f822c1097 /crates
parent23a62b06d697f2beb8350347de9ea4241f1430b5 (diff)
downloadrebel-61746b64b0e7087b17b21df6a1c7291ad25cd428.tar
rebel-61746b64b0e7087b17b21df6a1c7291ad25cd428.zip
runner: make lock() function more generic
Diffstat (limited to 'crates')
-rw-r--r--crates/runner/src/lib.rs18
-rw-r--r--crates/runner/src/util/unix.rs25
2 files changed, 27 insertions, 16 deletions
diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs
index af1e2a7..d0d8317 100644
--- a/crates/runner/src/lib.rs
+++ b/crates/runner/src/lib.rs
@@ -6,12 +6,11 @@ mod tar;
mod task;
mod util;
-use std::{fs::File, os::unix::prelude::AsRawFd, path::Path};
+use std::fs::File;
use capctl::prctl;
use ipc_channel::ipc;
use nix::{
- fcntl,
sched::CloneFlags,
sys::{signal, stat, wait},
unistd::{self, Gid, Uid},
@@ -19,7 +18,6 @@ use nix::{
use serde::{Deserialize, Serialize};
use common::{error::*, types::*};
-use util::fs;
use self::{
jobserver::Jobserver,
@@ -123,7 +121,8 @@ impl Runner {
///
/// Unsafe: Do not call in multithreaded processes
pub unsafe fn new(options: &Options) -> Result<Self> {
- let lockfile = Runner::lock()?;
+ let lockfile = unix::lock(paths::LOCKFILE, true, false)
+ .context("Failed to get lock on build directory, is another instance running?")?;
let uid = unistd::geteuid();
let gid = unistd::getegid();
@@ -144,17 +143,6 @@ impl Runner {
Ok(Runner { channel: tx })
}
- fn lock() -> Result<File> {
- let path = Path::new(paths::LOCKFILE);
- fs::mkdir(path.parent().unwrap())?;
- let file = fs::create(path)?;
-
- fcntl::flock(file.as_raw_fd(), fcntl::FlockArg::LockExclusiveNonblock)
- .context("Failed to get lock on build directory, is another instance running?")?;
-
- Ok(file)
- }
-
pub fn spawn(&self, task: &Task) -> ipc::IpcReceiver<Result<TaskOutput>> {
let (reply_tx, reply_rx) = ipc::channel().expect("IPC channel creation failed");
diff --git a/crates/runner/src/util/unix.rs b/crates/runner/src/util/unix.rs
index 48db764..710138c 100644
--- a/crates/runner/src/util/unix.rs
+++ b/crates/runner/src/util/unix.rs
@@ -1,4 +1,4 @@
-use std::os::unix::prelude::*;
+use std::{fs::File, os::unix::prelude::*, path::Path};
use nix::{
fcntl::{self, FcntlArg, FdFlag, OFlag},
@@ -8,6 +8,8 @@ use nix::{
use common::error::*;
+use super::fs;
+
pub fn set_blocking(fd: RawFd, blocking: bool) -> Result<()> {
let flags = unsafe {
OFlag::from_bits_unchecked(fcntl::fcntl(fd, FcntlArg::F_GETFL).context("fcntl(F_GETFL)")?)
@@ -59,3 +61,24 @@ pub fn nproc() -> Result<usize> {
Ok(count)
}
+
+pub fn lock<P: AsRef<Path>>(path: P, exclusive: bool, blocking: bool) -> Result<File> {
+ use fcntl::FlockArg::*;
+
+ if let Some(parent) = path.as_ref().parent() {
+ fs::mkdir(parent)?;
+ }
+
+ let arg = match (exclusive, blocking) {
+ (true, true) => LockExclusive,
+ (true, false) => LockExclusiveNonblock,
+ (false, true) => LockShared,
+ (false, false) => LockSharedNonblock,
+ };
+
+ let file = fs::create(path.as_ref())?;
+ fcntl::flock(file.as_raw_fd(), arg)
+ .with_context(|| format!("flock failed on {:?}", path.as_ref()))?;
+
+ Ok(file)
+}