Properly lock the builds of CA derivations
Make sure that we can’t build the same derivation twice at the same time. Fix https://github.com/NixOS/nix/issues/5029
This commit is contained in:
parent
1af3f63be5
commit
8707773965
|
@ -544,7 +544,7 @@ void DerivationGoal::tryToBuild()
|
||||||
PathSet lockFiles;
|
PathSet lockFiles;
|
||||||
/* FIXME: Should lock something like the drv itself so we don't build same
|
/* FIXME: Should lock something like the drv itself so we don't build same
|
||||||
CA drv concurrently */
|
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
|
/* 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. */
|
a build remote, but that would cause a deadlock. */
|
||||||
/* FIXME: Make it so we can use ourselves as a build remote even if we
|
/* FIXME: Make it so we can use ourselves as a build remote even if we
|
||||||
|
@ -552,9 +552,15 @@ void DerivationGoal::tryToBuild()
|
||||||
/* FIXME: find some way to lock for scheduling for the other stores so
|
/* 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.
|
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)
|
if (i.second.second)
|
||||||
lockFiles.insert(worker.store.Store::toRealPath(*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 (!outputLocks.lockPaths(lockFiles, "", false)) {
|
||||||
if (!actLock)
|
if (!actLock)
|
||||||
|
|
18
tests/ca/concurrent-builds.sh
Executable file
18
tests/ca/concurrent-builds.sh
Executable file
|
@ -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
tests/ca/racy.nix
Normal file
15
tests/ca/racy.nix
Normal file
|
@ -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 ]]
|
||||||
|
'';
|
||||||
|
}
|
|
@ -55,6 +55,7 @@ nix_tests = \
|
||||||
ca/nix-shell.sh \
|
ca/nix-shell.sh \
|
||||||
ca/nix-run.sh \
|
ca/nix-run.sh \
|
||||||
ca/recursive.sh \
|
ca/recursive.sh \
|
||||||
|
ca/concurrent-builds.sh \
|
||||||
ca/nix-copy.sh
|
ca/nix-copy.sh
|
||||||
# parallel.sh
|
# parallel.sh
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue