From c24ae9d7141157ed4cfb5c662288f1062e56c0ef Mon Sep 17 00:00:00 2001 From: damocles Date: Fri, 28 Aug 2026 17:39:13 +0200 Subject: [PATCH] hive-priv: fix doc comment attribution of nixos-container's flock --- hive-priv/src/main.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/hive-priv/src/main.rs b/hive-priv/src/main.rs index a6ac9bb7..96430c29 100644 --- a/hive-priv/src/main.rs +++ b/hive-priv/src/main.rs @@ -628,9 +628,14 @@ async fn exec( /// /// `update` builds the toplevel itself first and passes `--system-path` /// instead of `--flake` — see [`nix_build_toplevel`] for why. `create` -/// keeps the plain `--flake` form: `nixos-container`'s own `buildFlake()` -/// takes an internal `flock` for `create` (not for `update`), so the -/// hazard this works around doesn't apply there. +/// keeps the plain `--flake` form: `nixos-container` takes an exclusive +/// `flock` for the whole `create` action, and once `update` no longer +/// calls `buildFlake()` (below), concurrent `create`s are the only +/// remaining writers of the shared `.tmp` out-link — so they're mutually +/// excluded. ⚠️ That holds only while nothing else calls `buildFlake()` +/// unlocked: pre-this-PR, `create`'s own lock bought it nothing against a +/// concurrent *unlocked* `update` clobbering the same `.tmp` — the lock +/// alone was never what made `create` safe, this fix is. async fn container_flake_action( verb: &str, name: &str, @@ -678,9 +683,12 @@ fn toplevel_attr(name: &str) -> String { /// path* — `$systemPath` is only ever assigned from the CLI flag or from /// its own build result, so with no flag it stays `undef` and /// `"$systemPath.tmp"` interpolates to the bare string `.tmp` in -/// whatever the caller's cwd is. Worse, the `create` action's `flock` -/// around this isn't taken for `update` at all. hive-priv never sets a -/// per-call cwd, so two concurrent `update`s (this hive runs +/// whatever the caller's cwd is. `buildFlake()` itself takes no lock at +/// all — `create` wraps its *whole action* in an exclusive `flock` before +/// calling `buildFlake()`, but `update` calls it with no lock, so that +/// `create`-side lock never protected against a concurrent `update` +/// clobbering the same `.tmp`. hive-priv never sets a per-call cwd, so two +/// concurrent `update`s (this hive runs /// `services.hyperhive.c0re.buildSlots` > 1) share that one `.tmp`: one's /// `readlink(".tmp")` can resolve to the *other's* build output, handing /// an agent's container the wrong agent's closure — the "agent container