1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 06:52:43 +01:00

Merge remote-tracking branch 'upstream/master' into ca-floating-upstream

This commit is contained in:
John Ericson 2020-09-16 17:50:40 +00:00
commit c5ccebae00
19 changed files with 118 additions and 69 deletions

View file

@ -718,16 +718,25 @@ typedef enum {rpAccept, rpDecline, rpPostpone} HookReply;
class SubstitutionGoal;
/* Unless we are repairing, we don't both to test validity and just assume it,
so the choices are `Absent` or `Valid`. */
enum struct PathStatus {
Corrupt,
Absent,
Valid,
};
struct InitialOutputStatus {
StorePath path;
/* The output optional indicates whether it's already valid; i.e. exists
and is registered. If we're repairing, inner bool indicates whether the
valid path is in fact not corrupt. Otherwise, the inner bool is always
true (assumed no corruption). */
std::optional<bool> valid;
PathStatus status;
/* Valid in the store, and additionally non-corrupt if we are repairing */
bool isValid() const {
return valid && *valid;
return status == PathStatus::Valid;
}
/* Merely present, allowed to be corrupt */
bool isPresent() const {
return status == PathStatus::Corrupt
|| status == PathStatus::Valid;
}
};
@ -2186,10 +2195,10 @@ void DerivationGoal::startBuilder()
: !needsHashRewrite()
/* Can always use original path in sandbox */
? status.known->path
: !status.known->valid
: !status.known->isPresent()
/* If path doesn't yet exist can just use it */
? status.known->path
: buildMode != bmRepair && !*status.known->valid
: buildMode != bmRepair && !status.known->isValid()
/* If we aren't repairing we'll delete a corrupted path, so we
can use original path */
? status.known->path
@ -2199,7 +2208,7 @@ void DerivationGoal::startBuilder()
scratchOutputs.insert_or_assign(outputName, scratchPath);
/* A non-removed corrupted path needs to be stored here, too */
if (buildMode == bmRepair && !*status.known->valid)
if (buildMode == bmRepair && !status.known->isValid())
redirectedBadOutputs.insert(status.known->path);
/* Substitute output placeholders with the scratch output paths.
@ -4110,7 +4119,7 @@ void DerivationGoal::registerOutputs()
floating CA derivations and hash-mismatching fixed-output
derivations. */
PathLocks dynamicOutputLock;
auto optFixedPath = output.pathOpt(worker.store, drv->name, outputName);
auto optFixedPath = output.path(worker.store, drv->name, outputName);
if (!optFixedPath ||
worker.store.printStorePath(*optFixedPath) != finalDestPath)
{
@ -4289,26 +4298,32 @@ 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) {
if (useDerivation)
worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
else {
/* Once a floating CA derivations reaches this point, it must
already be resolved, drvPath the basic derivation path, and
a file existsing at that path for sake of the DB's foreign key. */
assert(drv->type() != DerivationType::CAFloating);
}
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) {
if (useDerivation)
worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
else {
/* Once a floating CA derivations reaches this point, it must
already be resolved, drvPath the basic derivation path, and
a file existsing at that path for sake of the DB's foreign key. */
assert(drv->type() != DerivationType::CAFloating);
}
}
}
@ -4601,7 +4616,7 @@ std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDeri
if (drv->type() != DerivationType::CAFloating) {
std::map<std::string, std::optional<StorePath>> res;
for (auto & [name, output] : drv->outputs)
res.insert_or_assign(name, output.pathOpt(worker.store, drv->name, name));
res.insert_or_assign(name, output.path(worker.store, drv->name, name));
return res;
} else {
return worker.store.queryPartialDerivationOutputMap(drvPath);
@ -4632,9 +4647,11 @@ void DerivationGoal::checkPathValidity()
auto outputPath = *i.second;
info.known = {
.path = outputPath,
.valid = !worker.store.isValidPath(outputPath)
? std::optional<bool> {}
: !checkHash || worker.pathContentsGood(outputPath),
.status = !worker.store.isValidPath(outputPath)
? PathStatus::Absent
: !checkHash || worker.pathContentsGood(outputPath)
? PathStatus::Valid
: PathStatus::Corrupt,
};
}
initialOutputs.insert_or_assign(i.first, info);