aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-02-08 13:23:55 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-02-08 13:23:55 +0000
commit3d74274b37a0f3b841ad860143f9c17401c3d7c4 (patch)
treeafd97d4cb2d2615e1b8470c4170871dbae198702 /src
parent60feff82cf4dd89c9039914c5b3ef8e1b8acf8e7 (diff)
* Updated `nix-store --verify' to the new schema.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/build.cc4
-rw-r--r--src/libstore/gc.cc2
-rw-r--r--src/libstore/misc.cc4
-rw-r--r--src/libstore/store.cc112
-rw-r--r--src/libstore/store.hh6
-rw-r--r--src/nix-store/main.cc4
6 files changed, 106 insertions, 26 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 64443d41a..3785c7da7 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -806,7 +806,7 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
{
s += *i;
PathSet references;
- queryReferences(*i, references);
+ queryReferences(noTxn, *i, references);
for (PathSet::iterator j = references.begin();
j != references.end(); ++j)
{
@@ -1326,7 +1326,7 @@ void SubstitutionGoal::init()
/* To maintain the closure invairant, we first have to realise the
paths referenced by this one. */
- queryReferences(storePath, references);
+ queryReferences(noTxn, storePath, references);
for (PathSet::iterator i = references.begin();
i != references.end(); ++i)
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 020712368..4d63d46ea 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -279,7 +279,7 @@ static void dfsVisit(const PathSet & paths, const Path & path,
PathSet references;
if (isValidPath(path))
- queryReferences(path, references);
+ queryReferences(noTxn, path, references);
for (PathSet::iterator i = references.begin();
i != references.end(); ++i)
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index b20879178..5f20ee277 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -19,9 +19,9 @@ void computeFSClosure(const Path & storePath,
PathSet references;
if (flipDirection)
- queryReferers(storePath, references);
+ queryReferers(noTxn, storePath, references);
else
- queryReferences(storePath, references);
+ queryReferences(noTxn, storePath, references);
for (PathSet::iterator i = references.begin();
i != references.end(); ++i)
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 693a388b3..0c7702f97 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -325,21 +325,23 @@ void setReferences(const Transaction & txn, const Path & storePath,
}
-void queryReferences(const Path & storePath, PathSet & references)
+void queryReferences(const Transaction & txn,
+ const Path & storePath, PathSet & references)
{
Paths references2;
- if (!isRealisablePath(noTxn, storePath))
+ if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath);
- nixDB.queryStrings(noTxn, dbReferences, storePath, references2);
+ nixDB.queryStrings(txn, dbReferences, storePath, references2);
references.insert(references2.begin(), references2.end());
}
-void queryReferers(const Path & storePath, PathSet & referers)
+void queryReferers(const Transaction & txn,
+ const Path & storePath, PathSet & referers)
{
- if (!isRealisablePath(noTxn, storePath))
+ if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath);
- PathSet referers2 = getReferers(noTxn, storePath);
+ PathSet referers2 = getReferers(txn, storePath);
referers.insert(referers2.begin(), referers2.end());
}
@@ -358,7 +360,7 @@ void setDeriver(const Transaction & txn, const Path & storePath,
Path queryDeriver(const Transaction & txn, const Path & storePath)
{
- if (!isRealisablePath(noTxn, storePath))
+ if (!isRealisablePath(txn, storePath))
throw Error(format("path `%1%' is not valid") % storePath);
Path deriver;
if (nixDB.queryString(txn, dbDerivers, storePath, deriver))
@@ -641,13 +643,8 @@ void verifyStore()
validPaths.insert(path);
}
- /* !!! the code below does not allow transitive substitutes.
- I.e., if B is a substitute of A, then B must be a valid path.
- B cannot itself be invalid but have a substitute. */
-
- /* "Usable" paths are those that are valid or have a substitute.
- These are the paths that are allowed to appear in the
- right-hand side of a sute mapping. */
+ /* "Usable" paths are those that are valid or have a
+ substitute. */
PathSet usablePaths(validPaths);
/* Check that the values of the substitute mappings are valid
@@ -656,10 +653,91 @@ void verifyStore()
nixDB.enumTable(txn, dbSubstitutes, subKeys);
for (Paths::iterator i = subKeys.begin(); i != subKeys.end(); ++i) {
Substitutes subs = readSubstitutes(txn, *i);
- if (subs.size() > 0)
- usablePaths.insert(*i);
- else
+ if (!isStorePath(*i)) {
+ printMsg(lvlError, format("found substitutes for non-store path `%1%'") % *i);
nixDB.delPair(txn, dbSubstitutes, *i);
+ }
+ else if (subs.size() == 0)
+ nixDB.delPair(txn, dbSubstitutes, *i);
+ else
+ usablePaths.insert(*i);
+ }
+
+ /* Check the cleanup invariant: only usable paths can have
+ `references', `referers', or `derivers' entries. */
+
+ /* Check the `derivers' table. */
+ Paths deriversKeys;
+ nixDB.enumTable(txn, dbDerivers, deriversKeys);
+ for (Paths::iterator i = deriversKeys.begin();
+ i != deriversKeys.end(); ++i)
+ {
+ if (usablePaths.find(*i) == usablePaths.end()) {
+ printMsg(lvlError, format("found deriver entry for unusable path `%1%'")
+ % *i);
+ nixDB.delPair(txn, dbDerivers, *i);
+ }
+ else {
+ Path deriver = queryDeriver(txn, *i);
+ if (!isStorePath(deriver)) {
+ printMsg(lvlError, format("found corrupt deriver `%1%' for `%2%'")
+ % deriver % *i);
+ nixDB.delPair(txn, dbDerivers, *i);
+ }
+ }
+ }
+
+ /* Check the `references' table. */
+ Paths referencesKeys;
+ nixDB.enumTable(txn, dbReferences, referencesKeys);
+ for (Paths::iterator i = referencesKeys.begin();
+ i != referencesKeys.end(); ++i)
+ {
+ if (usablePaths.find(*i) == usablePaths.end()) {
+ printMsg(lvlError, format("found references entry for unusable path `%1%'")
+ % *i);
+ nixDB.delPair(txn, dbReferences, *i);
+ }
+ else {
+ PathSet references;
+ queryReferences(txn, *i, references);
+ for (PathSet::iterator j = references.begin();
+ j != references.end(); ++j)
+ {
+ PathSet referers = getReferers(txn, *j);
+ if (referers.find(*i) == referers.end()) {
+ printMsg(lvlError, format("missing referer mapping from `%1%' to `%2%'")
+ % *j % *i);
+ }
+ }
+ }
+ }
+
+ /* Check the `referers' table. */
+ Paths referersKeys;
+ nixDB.enumTable(txn, dbReferers, referersKeys);
+ for (Paths::iterator i = referersKeys.begin();
+ i != referersKeys.end(); ++i)
+ {
+ if (usablePaths.find(*i) == usablePaths.end()) {
+ printMsg(lvlError, format("found referers entry for unusable path `%1%'")
+ % *i);
+ nixDB.delPair(txn, dbReferers, *i);
+ }
+ else {
+ PathSet referers;
+ queryReferers(txn, *i, referers);
+ for (PathSet::iterator j = referers.begin();
+ j != referers.end(); ++j)
+ {
+ Paths references;
+ nixDB.queryStrings(txn, dbReferences, *j, references);
+ if (find(references.begin(), references.end(), *i) == references.end()) {
+ printMsg(lvlError, format("missing reference mapping from `%1%' to `%2%'")
+ % *j % *i);
+ }
+ }
+ }
}
txn.commit();
diff --git a/src/libstore/store.hh b/src/libstore/store.hh
index 1f2b630e1..e981ade10 100644
--- a/src/libstore/store.hh
+++ b/src/libstore/store.hh
@@ -90,11 +90,13 @@ void setReferences(const Transaction & txn, const Path & storePath,
/* Queries the set of outgoing FS references for a store path. The
result is not cleared. */
-void queryReferences(const Path & storePath, PathSet & references);
+void queryReferences(const Transaction & txn,
+ const Path & storePath, PathSet & references);
/* Queries the set of incoming FS references for a store path. The
result is not cleared. */
-void queryReferers(const Path & storePath, PathSet & referers);
+void queryReferers(const Transaction & txn,
+ const Path & storePath, PathSet & referers);
/* Sets the deriver of a store path. Use with care! */
void setDeriver(const Transaction & txn, const Path & storePath,
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index f9bd3323f..a3c1b8fa7 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -215,8 +215,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
Path path = maybeUseOutput(*i, useOutput, forceRealise);
if (query == qRequisites)
storePathRequisites(path, includeOutputs, paths);
- else if (query == qReferences) queryReferences(path, paths);
- else if (query == qReferers) queryReferers(path, paths);
+ else if (query == qReferences) queryReferences(noTxn, path, paths);
+ else if (query == qReferers) queryReferers(noTxn, path, paths);
else if (query == qReferersClosure) computeFSClosure(path, paths, true);
}
printPathSet(paths);