Skip to content

Commit

Permalink
Properly lock the builds of CA derivations
Browse files Browse the repository at this point in the history
Make sure that we can’t build the same derivation twice at the same
time.

Fix #5029
  • Loading branch information
thufschmitt committed Jul 20, 2021
1 parent 1af3f63 commit 8707773
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -544,17 +544,23 @@ void DerivationGoal::tryToBuild()
PathSet lockFiles;
/* FIXME: Should lock something like the drv itself so we don't build same
CA drv concurrently */
if (dynamic_cast<LocalStore *>(&worker.store))
if (dynamic_cast<LocalStore *>(&worker.store)) {
/* If we aren't a local store, we might need to use the local store as
a build remote, but that would cause a deadlock. */
/* FIXME: Make it so we can use ourselves as a build remote even if we
are the local store (separate locking for building vs scheduling? */
/* FIXME: find some way to lock for scheduling for the other stores so
a forking daemon with --store still won't farm out redundant builds.
*/
for (auto & i : drv->outputsAndOptPaths(worker.store))
for (auto & i : drv->outputsAndOptPaths(worker.store)) {
if (i.second.second)
lockFiles.insert(worker.store.Store::toRealPath(*i.second.second));
else
lockFiles.insert(
worker.store.Store::toRealPath(drvPath) + "!" + i.first
);
}
}

if (!outputLocks.lockPaths(lockFiles, "", false)) {
if (!actLock)
Expand Down
18 changes: 18 additions & 0 deletions tests/ca/concurrent-builds.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

# Ensure that we can’t build twice the same derivation concurrently.
# Regression test for https://github.com/NixOS/nix/issues/5029

source common.sh

sed -i 's/experimental-features .*/& ca-derivations ca-references/' "$NIX_CONF_DIR"/nix.conf

export NIX_TESTS_CA_BY_DEFAULT=1

clearStore

for i in {0..5}; do
nix build --no-link --file ./racy.nix &
done

wait
15 changes: 15 additions & 0 deletions tests/ca/racy.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# A derivation that would certainly fail if several builders tried to
# build it at once.


with import ./config.nix;

mkDerivation {
name = "simple";
buildCommand = ''
mkdir $out
echo bar >> $out/foo
sleep 3
[[ "$(cat $out/foo)" == bar ]]
'';
}
1 change: 1 addition & 0 deletions tests/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ nix_tests = \
ca/nix-shell.sh \
ca/nix-run.sh \
ca/recursive.sh \
ca/concurrent-builds.sh \
ca/nix-copy.sh
# parallel.sh

Expand Down

0 comments on commit 8707773

Please sign in to comment.