diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2020-09-15 14:26:56 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2020-09-15 14:28:06 +0000 |
commit | c4bf219b55c76329988671d6b383d073373919f0 (patch) | |
tree | baef383027e57a30caca0a569d21a733aaf5677d /src/libstore/build.cc | |
parent | 3ba552b245e83e321227eea581e668bde87a652a (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/libstore/build.cc')
-rw-r--r-- | src/libstore/build.cc | 26 |
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); + } } |