From 450c358e2055488897349bf50951cce16ad9bc90 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Feb 2005 13:40:40 +0000 Subject: * Maintain a database table (`derivers') that maps output paths to the derivation that produced them. * `nix-store -qd PATH' prints out the derivation that produced a path. --- src/libstore/build.cc | 5 +++-- src/libstore/store.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++------- src/libstore/store.hh | 14 ++++++++++++-- src/nix-store/main.cc | 17 +++++++++++++++-- 4 files changed, 74 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 881f2dac8899..64443d41a785 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1140,7 +1140,8 @@ void DerivationGoal::computeClosure() { registerValidPath(txn, i->second.path, contentHashes[i->second.path], - allReferences[i->second.path]); + allReferences[i->second.path], + drvPath); } txn.commit(); @@ -1501,7 +1502,7 @@ void SubstitutionGoal::finished() Transaction txn; createStoreTransaction(txn); - registerValidPath(txn, storePath, contentHash, references); + registerValidPath(txn, storePath, contentHash, references, ""); txn.commit(); outputLock->setDeletion(true); diff --git a/src/libstore/store.cc b/src/libstore/store.cc index b915fce243a8..a3e98f69691d 100644 --- a/src/libstore/store.cc +++ b/src/libstore/store.cc @@ -56,6 +56,13 @@ static TableId dbReferers = 0; */ static TableId dbSubstitutes = 0; +/* dbDerivers :: Path -> [Path] + + This table lists the derivation used to build a path. There can + only be multiple such paths for fixed-output derivations (i.e., + derivations specifying an expected hash). */ +static TableId dbDerivers = 0; + bool Substitute::operator == (const Substitute & sub) { @@ -78,6 +85,7 @@ void openDB() dbReferences = nixDB.openTable("references"); dbReferers = nixDB.openTable("referers"); dbSubstitutes = nixDB.openTable("substitutes"); + dbDerivers = nixDB.openTable("derivers"); } @@ -318,6 +326,30 @@ void queryReferers(const Path & storePath, PathSet & referers) } +void setDeriver(const Transaction & txn, const Path & storePath, + const Path & deriver) +{ + assertStorePath(storePath); + if (deriver == "") return; + assertStorePath(deriver); + if (!isRealisablePath(txn, storePath)) + throw Error(format("path `%1%' is not valid") % storePath); + nixDB.setString(txn, dbDerivers, storePath, deriver); +} + + +Path queryDeriver(const Transaction & txn, const Path & storePath) +{ + if (!isRealisablePath(noTxn, storePath)) + throw Error(format("path `%1%' is not valid") % storePath); + Path deriver; + if (nixDB.queryString(txn, dbDerivers, storePath, deriver)) + return deriver; + else + return ""; +} + + static Substitutes readSubstitutes(const Transaction & txn, const Path & srcPath) { @@ -406,7 +438,8 @@ void clearSubstitutes() void registerValidPath(const Transaction & txn, - const Path & _path, const Hash & hash, const PathSet & references) + const Path & _path, const Hash & hash, const PathSet & references, + const Path & deriver) { Path path(canonPath(_path)); assertStorePath(path); @@ -423,6 +456,8 @@ void registerValidPath(const Transaction & txn, if (!isValidPathTxn(txn, *i)) throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid") % path % *i); + + setDeriver(txn, path, deriver); } @@ -433,11 +468,13 @@ static void invalidatePath(const Path & path, Transaction & txn) debug(format("unregistering path `%1%'") % path); /* Clear the `references' entry for this path, as well as the - inverse `referers' entries; but only if there are no - substitutes for this path. This maintains the cleanup - invariant. */ - if (querySubstitutes(txn, path).size() == 0) + inverse `referers' entries, and the `derivers' entry; but only + if there are no substitutes for this path. This maintains the + cleanup invariant. */ + if (querySubstitutes(txn, path).size() == 0) { setReferences(txn, path, PathSet()); + nixDB.delPair(txn, dbDerivers, path); + } nixDB.delPair(txn, dbValidPaths, path); } @@ -498,7 +535,7 @@ Path addToStore(const Path & _srcPath) canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, h, PathSet()); + registerValidPath(txn, dstPath, h, PathSet(), ""); txn.commit(); } @@ -534,7 +571,7 @@ Path addTextToStore(const string & suffix, const string & s, Transaction txn(nixDB); registerValidPath(txn, dstPath, - hashPath(htSHA256, dstPath), references); + hashPath(htSHA256, dstPath), references, ""); txn.commit(); } diff --git a/src/libstore/store.hh b/src/libstore/store.hh index 3a0b7a7131a2..95c738ed1bcc 100644 --- a/src/libstore/store.hh +++ b/src/libstore/store.hh @@ -57,7 +57,8 @@ void clearSubstitutes(); of the file system contents of the path. The hash must be a SHA-256 hash. */ void registerValidPath(const Transaction & txn, - const Path & path, const Hash & hash, const PathSet & references); + const Path & path, const Hash & hash, const PathSet & references, + const Path & deriver); /* Throw an exception if `path' is not directly in the Nix store. */ void assertStorePath(const Path & path); @@ -77,7 +78,8 @@ void canonicalisePathMetaData(const Path & path); /* Checks whether a path is valid. */ bool isValidPath(const Path & path); -/* Sets the set of outgoing FS references for a store path. */ +/* Sets the set of outgoing FS references for a store path. Use with + care! */ void setReferences(const Transaction & txn, const Path & storePath, const PathSet & references); @@ -89,6 +91,14 @@ void queryReferences(const Path & storePath, PathSet & references); result is not cleared. */ void queryReferers(const Path & storePath, PathSet & referers); +/* Sets the deriver of a store path. Use with care! */ +void setDeriver(const Transaction & txn, const Path & storePath, + const Path & deriver); + +/* Query the deriver of a store path. Return the empty string if no + deriver has been set. */ +Path queryDeriver(const Transaction & txn, const Path & storePath); + /* Constructs a unique store path name. */ Path makeStorePath(const string & type, const Hash & hash, const string & suffix); diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index d473475b821a..4b8d2cf3f75c 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -162,7 +162,7 @@ static void printPathSet(const PathSet & paths) static void opQuery(Strings opFlags, Strings opArgs) { enum { qOutputs, qRequisites, qReferences, qReferers, - qReferersClosure, qGraph } query = qOutputs; + qReferersClosure, qDeriver, qGraph } query = qOutputs; bool useOutput = false; bool includeOutputs = false; bool forceRealise = false; @@ -174,6 +174,7 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--references") query = qReferences; else if (*i == "--referers") query = qReferers; else if (*i == "--referers-closure") query = qReferersClosure; + else if (*i == "--deriver" || *i == "-d") query = qDeriver; else if (*i == "--graph") query = qGraph; else if (*i == "--use-output" || *i == "-u") useOutput = true; else if (*i == "--force-realise" || *i == "-f") forceRealise = true; @@ -214,6 +215,18 @@ static void opQuery(Strings opFlags, Strings opArgs) break; } + case qDeriver: + for (Strings::iterator i = opArgs.begin(); + i != opArgs.end(); i++) + { + *i = followSymlinks(*i); + Path deriver = queryDeriver(noTxn, *i); + cout << format("%1%\n") % + (deriver == "" ? "unknown-deriver" : deriver); + } + break; + + #if 0 case qGraph: { PathSet roots; @@ -288,7 +301,7 @@ static void opValidPath(Strings opFlags, Strings opArgs) createStoreTransaction(txn); for (Strings::iterator i = opArgs.begin(); i != opArgs.end(); ++i) - registerValidPath(txn, *i, hashPath(htSHA256, *i), PathSet()); + registerValidPath(txn, *i, hashPath(htSHA256, *i), PathSet(), ""); txn.commit(); } -- cgit 1.4.1