aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/db.cc10
-rw-r--r--src/db.hh5
-rw-r--r--src/fstate.hh4
-rw-r--r--src/nix.cc9
-rw-r--r--src/store.cc121
-rw-r--r--src/store.hh2
-rw-r--r--src/util.hh2
7 files changed, 139 insertions, 14 deletions
diff --git a/src/db.cc b/src/db.cc
index 64f9813a4..a8741342c 100644
--- a/src/db.cc
+++ b/src/db.cc
@@ -157,7 +157,7 @@ void delDB(const string & filename, const string & dbname,
void enumDB(const string & filename, const string & dbname,
- DBPairs & contents)
+ Strings & keys)
{
try {
@@ -168,11 +168,9 @@ void enumDB(const string & filename, const string & dbname,
DbcClose cursorCloser(cursor);
Dbt kt, dt;
- while (cursor->get(&kt, &dt, DB_NEXT) != DB_NOTFOUND) {
- string key((char *) kt.get_data(), kt.get_size());
- string data((char *) dt.get_data(), dt.get_size());
- contents.push_back(DBPair(key, data));
- }
+ while (cursor->get(&kt, &dt, DB_NEXT) != DB_NOTFOUND)
+ keys.push_back(
+ string((char *) kt.get_data(), kt.get_size()));
} catch (DbException e) { rethrow(e); }
}
diff --git a/src/db.hh b/src/db.hh
index aee6ce9bf..6f13eb30c 100644
--- a/src/db.hh
+++ b/src/db.hh
@@ -8,9 +8,6 @@
using namespace std;
-typedef pair<string, string> DBPair;
-typedef list<DBPair> DBPairs;
-
void createDB(const string & filename, const string & dbname);
bool queryDB(const string & filename, const string & dbname,
@@ -29,6 +26,6 @@ void delDB(const string & filename, const string & dbname,
const string & key);
void enumDB(const string & filename, const string & dbname,
- DBPairs & contents);
+ Strings & keys);
#endif /* !__DB_H */
diff --git a/src/fstate.hh b/src/fstate.hh
index 2ae876b7c..0d89e7e36 100644
--- a/src/fstate.hh
+++ b/src/fstate.hh
@@ -1,8 +1,6 @@
#ifndef __FSTATE_H
#define __FSTATE_H
-#include <set>
-
extern "C" {
#include <aterm2.h>
}
@@ -53,8 +51,6 @@ using namespace std;
typedef ATerm FState;
typedef ATerm Content;
-typedef set<string> StringSet;
-
typedef list<FSId> FSIds;
diff --git a/src/nix.cc b/src/nix.cc
index fe762798e..5785cd6b4 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -283,6 +283,13 @@ static void opInit(Strings opFlags, Strings opArgs)
}
+/* Verify the consistency of the Nix environment. */
+static void opVerify(Strings opFlags, Strings opArgs)
+{
+ verifyStore();
+}
+
+
/* Scan the arguments; find the operation, set global flags, put all
other flags in a list, and put all other arguments in another
list. */
@@ -316,6 +323,8 @@ void run(Strings args)
op = opRestore;
else if (arg == "--init")
op = opInit;
+ else if (arg == "--verify")
+ op = opVerify;
else if (arg[0] == '-')
opFlags.push_back(arg);
else
diff --git a/src/store.cc b/src/store.cc
index d75458d8a..864213692 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -260,3 +260,124 @@ void deleteFromStore(const string & path)
deletePath(path);
}
+
+
+void verifyStore()
+{
+ Strings paths;
+ enumDB(nixDB, dbPath2Id, paths);
+
+ for (Strings::iterator i = paths.begin();
+ i != paths.end(); i++)
+ {
+ bool erase = true;
+ string path = *i;
+
+ if (!pathExists(path)) {
+ debug(format("path `%1%' disappeared") % path);
+ }
+
+ else {
+ string id;
+ if (!queryDB(nixDB, dbPath2Id, path, id)) abort();
+
+ Strings idPaths;
+ queryListDB(nixDB, dbId2Paths, id, idPaths);
+
+ bool found = false;
+ for (Strings::iterator j = idPaths.begin();
+ j != idPaths.end(); j++)
+ if (path == *j) {
+ found = true;
+ break;
+ }
+
+ if (found)
+ erase = false;
+ else
+ /* !!! perhaps we should add path to idPaths? */
+ debug(format("reverse mapping for path `%1%' missing") % path);
+ }
+
+ if (erase) delDB(nixDB, dbPath2Id, path);
+ }
+
+ Strings ids;
+ enumDB(nixDB, dbId2Paths, ids);
+
+ for (Strings::iterator i = ids.begin();
+ i != ids.end(); i++)
+ {
+ FSId id = parseHash(*i);
+
+ Strings idPaths;
+ queryListDB(nixDB, dbId2Paths, id, idPaths);
+
+ for (Strings::iterator j = idPaths.begin();
+ j != idPaths.end(); )
+ {
+ string id2;
+ if (!queryDB(nixDB, dbPath2Id, *j, id2) ||
+ id != parseHash(id2)) {
+ debug(format("erasing path `%1%' from mapping for id %2%")
+ % *j % (string) id);
+ j = idPaths.erase(j);
+ } else j++;
+ }
+
+ setListDB(nixDB, dbId2Paths, id, idPaths);
+ }
+
+
+ Strings subs;
+ enumDB(nixDB, dbSubstitutes, subs);
+
+ for (Strings::iterator i = subs.begin();
+ i != subs.end(); i++)
+ {
+ FSId srcId = parseHash(*i);
+
+ Strings subIds;
+ queryListDB(nixDB, dbSubstitutes, srcId, subIds);
+
+ for (Strings::iterator j = subIds.begin();
+ j != subIds.end(); )
+ {
+ FSId subId = parseHash(*j);
+
+ Strings subPaths;
+ queryListDB(nixDB, dbId2Paths, subId, subPaths);
+ if (subPaths.size() == 0) {
+ debug(format("erasing substitute %1% for %2%")
+ % (string) subId % (string) srcId);
+ j = subIds.erase(j);
+ } else j++;
+ }
+
+ setListDB(nixDB, dbSubstitutes, srcId, subIds);
+ }
+
+ Strings sucs;
+ enumDB(nixDB, dbSuccessors, sucs);
+
+ for (Strings::iterator i = sucs.begin();
+ i != sucs.end(); i++)
+ {
+ FSId id1 = parseHash(*i);
+
+ string id2;
+ if (!queryDB(nixDB, dbSuccessors, id1, id2)) abort();
+
+ Strings id2Paths;
+ queryListDB(nixDB, dbId2Paths, id2, id2Paths);
+ if (id2Paths.size() == 0) {
+ Strings id2Subs;
+ queryListDB(nixDB, dbSubstitutes, id2, id2Subs);
+ if (id2Subs.size() == 0) {
+ debug(format("successor %1% for %2% missing")
+ % id2 % (string) id1);
+ delDB(nixDB, dbSuccessors, (string) id1);
+ }
+ }
+ }
+}
diff --git a/src/store.hh b/src/store.hh
index 7dd0f72e6..78d5529e7 100644
--- a/src/store.hh
+++ b/src/store.hh
@@ -35,5 +35,7 @@ void addToStore(string srcPath, string & dstPath, FSId & id,
/* Delete a value from the nixStore directory. */
void deleteFromStore(const string & path);
+void verifyStore();
+
#endif /* !__STORE_H */
diff --git a/src/util.hh b/src/util.hh
index 684bafbb5..611612a58 100644
--- a/src/util.hh
+++ b/src/util.hh
@@ -3,6 +3,7 @@
#include <string>
#include <list>
+#include <set>
#include <sstream>
#include <unistd.h>
@@ -38,6 +39,7 @@ public:
typedef list<string> Strings;
+typedef set<string> StringSet;
/* The canonical system name, as returned by config.guess. */