Skip to content

Commit 380b16e

Browse files
committed
Fix #9052
It's hard to reproduce this race condition going forward (e.g. it depends on the precise order that goals are scheduled, but https://github.com/roberth/nix-9052 current reproduces it, and this fixes that.
1 parent d904921 commit 380b16e

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/libstore/build/derivation-creation-and-realisation-goal.cc

+16-5
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,23 @@ void DerivationCreationAndRealisationGoal::addWantedOutputs(const OutputsSpec &
5151
{
5252
/* If we already want all outputs, there is nothing to do. */
5353
auto newWanted = wantedOutputs.union_(outputs);
54-
bool needRestart = !newWanted.isSubsetOf(wantedOutputs);
54+
bool moreWanted = !newWanted.isSubsetOf(wantedOutputs);
5555
wantedOutputs = newWanted;
5656

57-
if (!needRestart)
57+
if (!moreWanted)
5858
return;
5959

6060
if (!optDrvPath)
6161
// haven't started steps where the outputs matter yet
6262
return;
63-
worker.makeDerivationGoal(*optDrvPath, outputs, buildMode);
63+
auto g = worker.makeDerivationGoal(*optDrvPath, outputs, buildMode);
64+
65+
if (!(upcast_goal(g)->exitCode == ecSuccess || upcast_goal(g)->exitCode == ecFailed || upcast_goal(g)->exitCode == ecNoSubstituters || upcast_goal(g)->exitCode == ecIncompleteClosure)) {
66+
/* The original concrete goal has already finished and been
67+
destroyed, so reset this variable and double-suspend */
68+
concreteDrvGoal = g;
69+
needsRestart = true;
70+
}
6471
}
6572

6673
Goal::Co DerivationCreationAndRealisationGoal::init()
@@ -108,8 +115,12 @@ Goal::Co DerivationCreationAndRealisationGoal::init()
108115
g->preserveException = true;
109116
}
110117
optDrvPath = std::move(drvPath);
111-
addWaitee(upcast_goal(concreteDrvGoal));
112-
co_await Suspend{};
118+
119+
do {
120+
needsRestart = false;
121+
addWaitee(upcast_goal(concreteDrvGoal));
122+
co_await Suspend{};
123+
} while (needsRestart);
113124

114125
trace("outer build done");
115126

src/libstore/build/derivation-creation-and-realisation-goal.hh

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ struct DerivationCreationAndRealisationGoal : public Goal
4747
*/
4848
OutputsSpec wantedOutputs;
4949

50+
/**
51+
* Inner goal got recreated, need to wait again potentially.
52+
*/
53+
bool needsRestart = false;
54+
5055
/**
5156
* The final output paths of the build.
5257
*

0 commit comments

Comments
 (0)