From 6351b7e728518d662f8d867c94423b70ac607428 Mon Sep 17 00:00:00 2001 From: Wouter den Breejen Date: Fri, 22 Jun 2007 14:04:06 +0000 Subject: [PATCH] added dbValidStatePaths, StatePaths are now also registered as valid and can be query'd on validity --- src/libstore/build.cc | 19 ++++++--- src/libstore/local-store.cc | 75 +++++++++++++++++++++++++-------- src/libstore/local-store.hh | 9 +++- src/libstore/remote-store.cc | 17 ++++++++ src/libstore/remote-store.hh | 4 ++ src/libstore/store-api.hh | 6 +++ src/libstore/worker-protocol.hh | 2 + src/nix-worker/nix-worker.cc | 18 ++++++++ 8 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 859b094f6..016e850d4 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1620,6 +1620,7 @@ void DerivationGoal::computeClosure() { map allReferences; map allStateReferences; + map statePaths; map contentHashes; //TODO MOVE THIS TO A PLACE THAT ALSO GETS CALLED WHEN WE DONT NEED TO BUILD ANYTHING @@ -1737,9 +1738,10 @@ void DerivationGoal::computeClosure() i != drv.outputs.end(); ++i) { registerValidPath(txn, i->second.path, + "", //dummy statePath contentHashes[i->second.path], allReferences[i->second.path], - PathSet(), + PathSet(), //dummy stateReferences drvPath); } @@ -1785,7 +1787,11 @@ void DerivationGoal::computeClosure() PathSet state_references = scanForReferences(statePath, allPaths); PathSet state_stateReferences = scanForStateReferences(statePath, allStatePaths); all_state_references = mergePathSets(all_state_references, mergePathSets(state_references, state_stateReferences)); + + statePaths[path] = statePath; } + else + statePaths[path] = ""; for (PathSet::const_iterator i = allStatePaths.begin(); i != allStatePaths.end(); i++){ debug(format("all possible StatePaths: %1%") % (*i)); @@ -1795,14 +1801,17 @@ void DerivationGoal::computeClosure() } allStateReferences[path] = all_state_references; + } for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i) { - registerValidPath(txn, i->second.path, + registerValidPath(txn, + i->second.path, //component path + statePaths[i->second.path], //state path contentHashes[i->second.path], - allReferences[i->second.path], - allStateReferences[i->second.path], + allReferences[i->second.path], //set of component-references + allStateReferences[i->second.path], //set of state-references drvPath); } @@ -2206,7 +2215,7 @@ void SubstitutionGoal::finished() Transaction txn; createStoreTransaction(txn); - registerValidPath(txn, storePath, contentHash, + registerValidPath(txn, storePath, "", contentHash, //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! replace "" with a substitued state path !!!!!!!! references, stateReferences, sub.deriver); txn.commit(); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 723d31e10..72c2da48a 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -36,6 +36,12 @@ static Database nixDB; is, produced by a succesful build). */ static TableId dbValidPaths = 0; +/* dbValidStatePaths :: Path -> () + + The existence of a key $p$ indicates that state path $p$ is valid (that + is, produced by a succesful build). */ +static TableId dbValidStatePaths = 0; + /* dbReferences :: Path -> [Path] This table lists the outgoing file system references for each @@ -165,6 +171,7 @@ LocalStore::LocalStore(bool reserveSpace) return; } dbValidPaths = nixDB.openTable("validpaths"); + dbValidStatePaths = nixDB.openTable("validpaths_state"); dbReferences = nixDB.openTable("references"); dbReferrers = nixDB.openTable("referrers", true); /* must be sorted */ dbSubstitutes = nixDB.openTable("substitutes"); @@ -307,12 +314,32 @@ bool isValidPathTxn(const Transaction & txn, const Path & path) return nixDB.queryString(txn, dbValidPaths, path, s); } - bool LocalStore::isValidPath(const Path & path) { return isValidPathTxn(noTxn, path); } +bool isValidStatePathTxn(const Transaction & txn, const Path & path) +{ + string s; + return nixDB.queryString(txn, dbValidStatePaths, path, s); +} + +bool LocalStore::isValidStatePath(const Path & path) +{ + return isValidStatePathTxn(noTxn, path); +} + +bool isValidComponentOrStatePathTxn(const Transaction & txn, const Path & path) +{ + return (isValidPathTxn(txn, path) || isValidStatePathTxn(txn, path)); +} + +bool LocalStore::isValidComponentOrStatePath(const Path & path) +{ + return isValidComponentOrStatePathTxn(noTxn, path); +} + static Substitutes readSubstitutes(const Transaction & txn, const Path & srcPath); @@ -736,13 +763,20 @@ void clearSubstitutes() } -static void setHash(const Transaction & txn, const Path & storePath, - const Hash & hash) +static void setHash(const Transaction & txn, const Path & storePath, const Hash & hash, bool stateHash = false) { assert(hash.type == htSHA256); - nixDB.setString(txn, dbValidPaths, storePath, "sha256:" + printHash(hash)); + + if(stateHash) + nixDB.setString(txn, dbValidStatePaths, storePath, "sha256:" + printHash(hash)); + else + nixDB.setString(txn, dbValidPaths, storePath, "sha256:" + printHash(hash)); } +static void setStateHash(const Transaction & txn, const Path & storePath, const Hash & hash) +{ + setHash(txn, storePath, hash, true); +} static Hash queryHash(const Transaction & txn, const Path & storePath) { @@ -769,12 +803,13 @@ Hash LocalStore::queryPathHash(const Path & path) void registerValidPath(const Transaction & txn, - const Path & path, const Hash & hash, + const Path & path, const Path & statePath, const Hash & hash, const PathSet & references, const PathSet & stateReferences, const Path & deriver) { ValidPathInfo info; info.path = path; + info.statePath = statePath; info.hash = hash; info.references = references; info.stateReferences = stateReferences; @@ -788,28 +823,30 @@ void registerValidPath(const Transaction & txn, void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos) { PathSet newPaths; - for (ValidPathInfos::const_iterator i = infos.begin(); - i != infos.end(); ++i) + for (ValidPathInfos::const_iterator i = infos.begin(); i != infos.end(); ++i) newPaths.insert(i->path); - for (ValidPathInfos::const_iterator i = infos.begin(); - i != infos.end(); ++i) + for (ValidPathInfos::const_iterator i = infos.begin(); i != infos.end(); ++i) { assertStorePath(i->path); debug(format("registering path `%1%'") % i->path); setHash(txn, i->path, i->hash); + if (i->statePath != "") + setStateHash(txn, i->statePath, Hash()); //the hash value in the db now becomes empty, but if the key exists, we know that the state path is valid + setReferences(txn, i->path, i->references, i->stateReferences); - - /* Check that all referenced paths are also valid (or about to - become valid). */ + + /* Check that all referenced paths are also valid (or about to) become valid). */ for (PathSet::iterator j = i->references.begin(); j != i->references.end(); ++j) if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end()) throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid") % i->path % *j); + //TODO Also do this for stateReferences???? + setDeriver(txn, i->path, i->deriver); } } @@ -817,7 +854,7 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos) /* Invalidate a path. The caller is responsible for checking that there are no referrers. */ -static void invalidatePath(Transaction & txn, const Path & path) +static void invalidatePath(Transaction & txn, const Path & path) //TODO Adjust for state paths???? { debug(format("unregistering path `%1%'") % path); @@ -830,7 +867,7 @@ static void invalidatePath(Transaction & txn, const Path & path) nixDB.delPair(txn, dbDerivers, path); //TODO!!!!! also for state Derivers!!!!!!!!!!!!!!! } - nixDB.delPair(txn, dbValidPaths, path); //Always? + nixDB.delPair(txn, dbValidPaths, path); } @@ -868,7 +905,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, h, PathSet(), PathSet(), ""); + registerValidPath(txn, dstPath, "", h, PathSet(), PathSet(), ""); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECK if the first "" (statepath) is needed here txn.commit(); } @@ -902,7 +939,8 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, hashPath(htSHA256, dstPath), references, PathSet(), ""); //There are no stateReferences in drvs..... so we dont need to register them (I think) + registerValidPath(txn, dstPath, "", hashPath(htSHA256, dstPath), references, PathSet(), ""); //There are no stateReferences in drvs..... so we dont need to register them (I think) + //A drvs has also no statepath, so that is ok... txn.commit(); } @@ -1107,7 +1145,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) /* !!! if we were clever, we could prevent the hashPath() here. */ if (!isValidPath(deriver)) deriver = ""; - registerValidPath(txn, dstPath, + registerValidPath(txn, dstPath, "", //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! replace "" for a state path ?????? hashPath(htSHA256, dstPath), references, stateReferences, deriver); txn.commit(); } @@ -1183,6 +1221,9 @@ void verifyStore(bool checkContents) /* "Realisable" paths are those that are valid or have a substitute. */ PathSet realisablePaths(validPaths); + + + //TODO Do also for validStatePaths /* Check that the values of the substitute mappings are valid paths. */ diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index aa539ddda..0a8925744 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -40,7 +40,11 @@ public: /* Implementations of abstract store API methods. */ bool isValidPath(const Path & path); - + + bool isValidStatePath(const Path & path); + + bool isValidComponentOrStatePath(const Path & path); + Substitutes querySubstitutes(const Path & srcPath); Hash queryPathHash(const Path & path); @@ -115,13 +119,14 @@ 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 Path & path, const Path & statepath, const Hash & hash, const PathSet & references, const PathSet & stateReferences, const Path & deriver); struct ValidPathInfo { Path path; + Path statePath; Path deriver; Hash hash; PathSet references; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 02e153f71..c299da2c2 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -163,6 +163,23 @@ bool RemoteStore::isValidPath(const Path & path) return reply != 0; } +bool RemoteStore::isValidStatePath(const Path & path) +{ + writeInt(wopIsValidStatePath, to); + writeString(path, to); + processStderr(); + unsigned int reply = readInt(from); + return reply != 0; +} + +bool RemoteStore::isValidComponentOrStatePath(const Path & path) +{ + writeInt(wopIsValidComponentOrStatePath, to); + writeString(path, to); + processStderr(); + unsigned int reply = readInt(from); + return reply != 0; +} Substitutes RemoteStore::querySubstitutes(const Path & path) { diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 3f3006b0d..c5d7ca755 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -26,6 +26,10 @@ public: /* Implementations of abstract store API methods. */ bool isValidPath(const Path & path); + + bool isValidStatePath(const Path & path); + + bool isValidComponentOrStatePath(const Path & path); Substitutes querySubstitutes(const Path & path); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index bcf9b19d4..a1de65b56 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -58,6 +58,12 @@ public: /* Checks whether a path is valid. */ virtual bool isValidPath(const Path & path) = 0; + + /* TODO */ + virtual bool isValidStatePath(const Path & path) = 0; + + /* TODO */ + virtual bool isValidComponentOrStatePath(const Path & path) = 0; /* Return the substitutes for the given path. */ virtual Substitutes querySubstitutes(const Path & path) = 0; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index 2d064cca9..343664c80 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -12,6 +12,8 @@ namespace nix { typedef enum { wopQuit, wopIsValidPath, + wopIsValidStatePath, + wopIsValidComponentOrStatePath, wopQuerySubstitutes, wopHasSubstitutes, wopQueryPathHash, diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index 4b16b7519..ec34eb727 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -244,6 +244,24 @@ static void performOp(Source & from, Sink & to, unsigned int op) writeInt(result, to); break; } + + case wopIsValidStatePath: { + Path path = readStorePath(from); + startWork(); + bool result = store->isValidStatePath(path); + stopWork(); + writeInt(result, to); + break; + } + + case wopIsValidComponentOrStatePath: { + Path path = readStorePath(from); + startWork(); + bool result = store->isValidComponentOrStatePath(path); + stopWork(); + writeInt(result, to); + break; + } case wopHasSubstitutes: { Path path = readStorePath(from);