From 066da4ab852ebe4288536149824ea175dc36cad4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 25 Jan 2005 17:08:52 +0000 Subject: * Really fix the substitute mechanism, i.e., ensure the closure invariant by registering references through the manifest. * Added a test for nix-pull. --- src/libstore/build.cc | 39 ++++++++++++++++++++++++++++++++------- src/libstore/store.cc | 8 ++++---- 2 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 026721f3b..7dd7412e9 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -472,9 +472,8 @@ void DerivationGoal::outputsSubstituted() { trace("all outputs substituted (maybe)"); - if (nrFailed > 0 && !tryFallback) { + if (nrFailed > 0 && !tryFallback) throw Error(format("some substitutes for the outputs of derivation `%1%' failed; try `--fallback'") % drvPath); - } nrFailed = 0; @@ -1252,6 +1251,9 @@ private: /* The current substitute. */ Substitute sub; + /* Outgoing references for this path. */ + PathSet references; + /* Pipe for the substitute's standard output/error. */ Pipe logPipe; @@ -1272,6 +1274,7 @@ public: /* The states. */ void init(); + void referencesValid(); void tryNext(); void tryToRun(); void finished(); @@ -1313,13 +1316,35 @@ void SubstitutionGoal::init() return; } - /* !!! build the outgoing references of this path first to - maintain the closure invariant! */ - - /* Otherwise, get the substitutes. */ + /* Read the substitutes. */ subs = querySubstitutes(storePath); - /* Try the first one. */ + /* To maintain the closure invairant, we first have to realise the + paths referenced by this one. */ + queryReferences(storePath, references); + + for (PathSet::iterator i = references.begin(); + i != references.end(); ++i) + addWaitee(worker.makeSubstitutionGoal(*i)); + + if (waitees.empty()) /* to prevent hang (no wake-up event) */ + referencesValid(); + else + state = &SubstitutionGoal::referencesValid; +} + + +void SubstitutionGoal::referencesValid() +{ + trace("all referenced realised"); + + if (nrFailed > 0) + throw Error(format("some references of path `%1%' could not be realised") % storePath); + + for (PathSet::iterator i = references.begin(); + i != references.end(); ++i) + assert(isValidPath(*i)); + tryNext(); } diff --git a/src/libstore/store.cc b/src/libstore/store.cc index 97b7f5fe8..02bf9803b 100644 --- a/src/libstore/store.cc +++ b/src/libstore/store.cc @@ -265,8 +265,8 @@ void setReferences(const Transaction & txn, const Path & storePath, void queryReferences(const Path & storePath, PathSet & references) { Paths references2; - if (!isValidPath(storePath)) - throw Error(format("path `%1%' is not valid") % storePath); + // if (!isValidPath(storePath)) + // throw Error(format("path `%1%' is not valid") % storePath); nixDB.queryStrings(noTxn, dbReferences, storePath, references2); references.insert(references2.begin(), references2.end()); } @@ -275,8 +275,8 @@ void queryReferences(const Path & storePath, PathSet & references) void queryReferers(const Path & storePath, PathSet & referers) { Paths referers2; - if (!isValidPath(storePath)) - throw Error(format("path `%1%' is not valid") % storePath); + // if (!isValidPath(storePath)) + // throw Error(format("path `%1%' is not valid") % storePath); nixDB.queryStrings(noTxn, dbReferers, storePath, referers2); referers.insert(referers2.begin(), referers2.end()); } -- cgit v1.2.3