From e57b743058836ef34d4dd96fca5d6152f910140c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 26 Oct 2021 17:14:07 +0200 Subject: runner: hold lock on task state dir while task is running Do not allow concurrent runs of the same task. --- crates/runner/src/paths.rs | 8 +++++++- crates/runner/src/task.rs | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/runner/src/paths.rs b/crates/runner/src/paths.rs index 9539782..5bfef25 100644 --- a/crates/runner/src/paths.rs +++ b/crates/runner/src/paths.rs @@ -21,7 +21,9 @@ //! │ │ ├── layer/ # overlayfs layer dir (moved to layer/ after build) //! │ │ ├── work/ # overlayfs work dir (discarded after build) //! │ │ ├── task.json.tmp # during write -//! │ │ └── task.json # after write +//! │ │ ├── task.json # after write +//! │ │ ├── task.log # stdout/stderr output of the task +//! │ │ └── task.lock # task lockfile //! │   └── ... //! └── tmp/ # tmpfs (mounted on start of rebel) //!    ├── rootfs/ # unpacked rootfs.tar @@ -95,6 +97,10 @@ pub fn task_log_filename(hash: &InputHash) -> String { join(&[TASK_STATE_DIR, &hash.to_string(), "task.log"]) } +pub fn task_lock_filename(hash: &InputHash) -> String { + join(&[TASK_STATE_DIR, &hash.to_string(), "task.lock"]) +} + pub fn layer_dir(hash: &LayerHash) -> String { join(&[LAYER_STATE_DIR, &hash.to_string()]) } diff --git a/crates/runner/src/task.rs b/crates/runner/src/task.rs index 659b04d..ff27399 100644 --- a/crates/runner/src/task.rs +++ b/crates/runner/src/task.rs @@ -24,7 +24,7 @@ use super::{ ns, tar, util::{cjson, fs, Checkable}, }; -use crate::paths; +use crate::{paths, util::unix}; const BUILD_UID: Uid = Uid::from_raw(1000); const BUILD_GID: Gid = Gid::from_raw(1000); @@ -433,6 +433,10 @@ fn save_cached(input_hash: &InputHash, output: &TaskOutput) -> Result<()> { pub fn handle(task: Task, jobserver: Jobserver) -> Result { let input_hash = input_hash(&task); + // TODO: We should not hold a job token while waiting on the lock + let _lock = unix::lock(paths::task_lock_filename(&input_hash), true, true) + .context("Failed to get task lock")?; + if let Ok(task_output) = load_cached(&input_hash) { return Ok(task_output); } -- cgit v1.2.3