1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 12:10:59 +01:00

added dbValidStatePaths, StatePaths are now also registered as valid and can be query'd on validity

This commit is contained in:
Wouter den Breejen 2007-06-22 14:04:06 +00:00
parent 51fad07fbd
commit 6351b7e728
8 changed files with 126 additions and 24 deletions

View file

@ -1620,6 +1620,7 @@ void DerivationGoal::computeClosure()
{ {
map<Path, PathSet> allReferences; map<Path, PathSet> allReferences;
map<Path, PathSet> allStateReferences; map<Path, PathSet> allStateReferences;
map<Path, Path> statePaths;
map<Path, Hash> contentHashes; map<Path, Hash> contentHashes;
//TODO MOVE THIS TO A PLACE THAT ALSO GETS CALLED WHEN WE DONT NEED TO BUILD ANYTHING //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) i != drv.outputs.end(); ++i)
{ {
registerValidPath(txn, i->second.path, registerValidPath(txn, i->second.path,
"", //dummy statePath
contentHashes[i->second.path], contentHashes[i->second.path],
allReferences[i->second.path], allReferences[i->second.path],
PathSet(), PathSet(), //dummy stateReferences
drvPath); drvPath);
} }
@ -1785,7 +1787,11 @@ void DerivationGoal::computeClosure()
PathSet state_references = scanForReferences(statePath, allPaths); PathSet state_references = scanForReferences(statePath, allPaths);
PathSet state_stateReferences = scanForStateReferences(statePath, allStatePaths); PathSet state_stateReferences = scanForStateReferences(statePath, allStatePaths);
all_state_references = mergePathSets(all_state_references, mergePathSets(state_references, state_stateReferences)); 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++){ for (PathSet::const_iterator i = allStatePaths.begin(); i != allStatePaths.end(); i++){
debug(format("all possible StatePaths: %1%") % (*i)); debug(format("all possible StatePaths: %1%") % (*i));
@ -1795,14 +1801,17 @@ void DerivationGoal::computeClosure()
} }
allStateReferences[path] = all_state_references; allStateReferences[path] = all_state_references;
} }
for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i) 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], contentHashes[i->second.path],
allReferences[i->second.path], allReferences[i->second.path], //set of component-references
allStateReferences[i->second.path], allStateReferences[i->second.path], //set of state-references
drvPath); drvPath);
} }
@ -2206,7 +2215,7 @@ void SubstitutionGoal::finished()
Transaction txn; Transaction txn;
createStoreTransaction(txn); createStoreTransaction(txn);
registerValidPath(txn, storePath, contentHash, registerValidPath(txn, storePath, "", contentHash, //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! replace "" with a substitued state path !!!!!!!!
references, stateReferences, sub.deriver); references, stateReferences, sub.deriver);
txn.commit(); txn.commit();

View file

@ -36,6 +36,12 @@ static Database nixDB;
is, produced by a succesful build). */ is, produced by a succesful build). */
static TableId dbValidPaths = 0; 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] /* dbReferences :: Path -> [Path]
This table lists the outgoing file system references for each This table lists the outgoing file system references for each
@ -165,6 +171,7 @@ LocalStore::LocalStore(bool reserveSpace)
return; return;
} }
dbValidPaths = nixDB.openTable("validpaths"); dbValidPaths = nixDB.openTable("validpaths");
dbValidStatePaths = nixDB.openTable("validpaths_state");
dbReferences = nixDB.openTable("references"); dbReferences = nixDB.openTable("references");
dbReferrers = nixDB.openTable("referrers", true); /* must be sorted */ dbReferrers = nixDB.openTable("referrers", true); /* must be sorted */
dbSubstitutes = nixDB.openTable("substitutes"); dbSubstitutes = nixDB.openTable("substitutes");
@ -307,12 +314,32 @@ bool isValidPathTxn(const Transaction & txn, const Path & path)
return nixDB.queryString(txn, dbValidPaths, path, s); return nixDB.queryString(txn, dbValidPaths, path, s);
} }
bool LocalStore::isValidPath(const Path & path) bool LocalStore::isValidPath(const Path & path)
{ {
return isValidPathTxn(noTxn, 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, static Substitutes readSubstitutes(const Transaction & txn,
const Path & srcPath); const Path & srcPath);
@ -736,13 +763,20 @@ void clearSubstitutes()
} }
static void setHash(const Transaction & txn, const Path & storePath, static void setHash(const Transaction & txn, const Path & storePath, const Hash & hash, bool stateHash = false)
const Hash & hash)
{ {
assert(hash.type == htSHA256); assert(hash.type == htSHA256);
if(stateHash)
nixDB.setString(txn, dbValidStatePaths, storePath, "sha256:" + printHash(hash));
else
nixDB.setString(txn, dbValidPaths, storePath, "sha256:" + printHash(hash)); 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) static Hash queryHash(const Transaction & txn, const Path & storePath)
{ {
@ -769,12 +803,13 @@ Hash LocalStore::queryPathHash(const Path & path)
void registerValidPath(const Transaction & txn, 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 PathSet & references, const PathSet & stateReferences,
const Path & deriver) const Path & deriver)
{ {
ValidPathInfo info; ValidPathInfo info;
info.path = path; info.path = path;
info.statePath = statePath;
info.hash = hash; info.hash = hash;
info.references = references; info.references = references;
info.stateReferences = stateReferences; info.stateReferences = stateReferences;
@ -788,28 +823,30 @@ void registerValidPath(const Transaction & txn,
void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos) void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos)
{ {
PathSet newPaths; PathSet newPaths;
for (ValidPathInfos::const_iterator i = infos.begin(); for (ValidPathInfos::const_iterator i = infos.begin(); i != infos.end(); ++i)
i != infos.end(); ++i)
newPaths.insert(i->path); newPaths.insert(i->path);
for (ValidPathInfos::const_iterator i = infos.begin(); for (ValidPathInfos::const_iterator i = infos.begin(); i != infos.end(); ++i)
i != infos.end(); ++i)
{ {
assertStorePath(i->path); assertStorePath(i->path);
debug(format("registering path `%1%'") % i->path); debug(format("registering path `%1%'") % i->path);
setHash(txn, i->path, i->hash); 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); setReferences(txn, i->path, i->references, i->stateReferences);
/* Check that all referenced paths are also valid (or about to /* Check that all referenced paths are also valid (or about to) become valid). */
become valid). */
for (PathSet::iterator j = i->references.begin(); for (PathSet::iterator j = i->references.begin();
j != i->references.end(); ++j) j != i->references.end(); ++j)
if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end()) if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end())
throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid") throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
% i->path % *j); % i->path % *j);
//TODO Also do this for stateReferences????
setDeriver(txn, i->path, i->deriver); 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 /* Invalidate a path. The caller is responsible for checking that
there are no referrers. */ 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); 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, 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); canonicalisePathMetaData(dstPath);
Transaction txn(nixDB); 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(); txn.commit();
} }
@ -902,7 +939,8 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s,
canonicalisePathMetaData(dstPath); canonicalisePathMetaData(dstPath);
Transaction txn(nixDB); 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(); txn.commit();
} }
@ -1107,7 +1145,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
/* !!! if we were clever, we could prevent the hashPath() /* !!! if we were clever, we could prevent the hashPath()
here. */ here. */
if (!isValidPath(deriver)) deriver = ""; if (!isValidPath(deriver)) deriver = "";
registerValidPath(txn, dstPath, registerValidPath(txn, dstPath, "", //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! replace "" for a state path ??????
hashPath(htSHA256, dstPath), references, stateReferences, deriver); hashPath(htSHA256, dstPath), references, stateReferences, deriver);
txn.commit(); txn.commit();
} }
@ -1184,6 +1222,9 @@ void verifyStore(bool checkContents)
substitute. */ substitute. */
PathSet realisablePaths(validPaths); PathSet realisablePaths(validPaths);
//TODO Do also for validStatePaths
/* Check that the values of the substitute mappings are valid /* Check that the values of the substitute mappings are valid
paths. */ paths. */
Paths subKeys; Paths subKeys;

View file

@ -41,6 +41,10 @@ public:
bool isValidPath(const Path & path); bool isValidPath(const Path & path);
bool isValidStatePath(const Path & path);
bool isValidComponentOrStatePath(const Path & path);
Substitutes querySubstitutes(const Path & srcPath); Substitutes querySubstitutes(const Path & srcPath);
Hash queryPathHash(const Path & path); Hash queryPathHash(const Path & path);
@ -115,13 +119,14 @@ void clearSubstitutes();
of the file system contents of the path. The hash must be a of the file system contents of the path. The hash must be a
SHA-256 hash. */ SHA-256 hash. */
void registerValidPath(const Transaction & txn, 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 PathSet & references, const PathSet & stateReferences,
const Path & deriver); const Path & deriver);
struct ValidPathInfo struct ValidPathInfo
{ {
Path path; Path path;
Path statePath;
Path deriver; Path deriver;
Hash hash; Hash hash;
PathSet references; PathSet references;

View file

@ -163,6 +163,23 @@ bool RemoteStore::isValidPath(const Path & path)
return reply != 0; 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) Substitutes RemoteStore::querySubstitutes(const Path & path)
{ {

View file

@ -27,6 +27,10 @@ public:
bool isValidPath(const Path & path); bool isValidPath(const Path & path);
bool isValidStatePath(const Path & path);
bool isValidComponentOrStatePath(const Path & path);
Substitutes querySubstitutes(const Path & path); Substitutes querySubstitutes(const Path & path);
bool hasSubstitutes(const Path & path); bool hasSubstitutes(const Path & path);

View file

@ -59,6 +59,12 @@ public:
/* Checks whether a path is valid. */ /* Checks whether a path is valid. */
virtual bool isValidPath(const Path & path) = 0; 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. */ /* Return the substitutes for the given path. */
virtual Substitutes querySubstitutes(const Path & path) = 0; virtual Substitutes querySubstitutes(const Path & path) = 0;

View file

@ -12,6 +12,8 @@ namespace nix {
typedef enum { typedef enum {
wopQuit, wopQuit,
wopIsValidPath, wopIsValidPath,
wopIsValidStatePath,
wopIsValidComponentOrStatePath,
wopQuerySubstitutes, wopQuerySubstitutes,
wopHasSubstitutes, wopHasSubstitutes,
wopQueryPathHash, wopQueryPathHash,

View file

@ -245,6 +245,24 @@ static void performOp(Source & from, Sink & to, unsigned int op)
break; 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: { case wopHasSubstitutes: {
Path path = readStorePath(from); Path path = readStorePath(from);
startWork(); startWork();