aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2020-09-15 14:26:56 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2020-09-15 14:28:06 +0000
commitc4bf219b55c76329988671d6b383d073373919f0 (patch)
treebaef383027e57a30caca0a569d21a733aaf5677d /src
parent3ba552b245e83e321227eea581e668bde87a652a (diff)
Don't link deriver until after any delayed exception is thrown
Otherwise, we will associate fixed-output derivations with outputs that they did indeed produce, but which had the wrong hash. That's no good.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/build.cc26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 9eff03f7b..d6a775ae9 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -4251,22 +4251,28 @@ void DerivationGoal::registerOutputs()
/* Register each output path as valid, and register the sets of
paths referenced by each of them. If there are cycles in the
outputs, this will fail. */
- {
- ValidPathInfos infos2;
- for (auto & [outputName, newInfo] : infos) {
- /* FIXME: we will want to track this mapping in the DB whether or
- not we have a drv file. */
- if (useDerivation)
- worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
- infos2.push_back(newInfo);
- }
- worker.store.registerValidPaths(infos2);
+ ValidPathInfos infos2;
+ for (auto & [outputName, newInfo] : infos) {
+ infos2.push_back(newInfo);
}
+ worker.store.registerValidPaths(infos2);
/* In case of a fixed-output derivation hash mismatch, throw an
exception now that we have registered the output as valid. */
if (delayedException)
std::rethrow_exception(delayedException);
+
+ /* If we made it this far, we are sure the output matches the derivation
+ (since the delayedException would be a fixed output CA mismatch). That
+ means it's safe to link the derivation to the output hash. We must do
+ that for floating CA derivations, which otherwise couldn't be cached,
+ but it's fine to do in all cases. */
+ for (auto & [outputName, newInfo] : infos) {
+ /* FIXME: we will want to track this mapping in the DB whether or
+ not we have a drv file. */
+ if (useDerivation)
+ worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
+ }
}