* `nix --verify': check and repair reverse mapping for successors.
This commit is contained in:
parent
d3d5e77810
commit
0abe185688
2 changed files with 32 additions and 88 deletions
116
src/store.cc
116
src/store.cc
|
@ -82,25 +82,25 @@ void copyPath(const Path & src, const Path & dst)
|
||||||
|
|
||||||
|
|
||||||
void registerSuccessor(const Transaction & txn,
|
void registerSuccessor(const Transaction & txn,
|
||||||
const Path & path1, const Path & path2)
|
const Path & srcPath, const Path & sucPath)
|
||||||
{
|
{
|
||||||
Path known;
|
Path known;
|
||||||
if (nixDB.queryString(txn, dbSuccessors, path1, known) &&
|
if (nixDB.queryString(txn, dbSuccessors, srcPath, known) &&
|
||||||
known != path2)
|
known != sucPath)
|
||||||
{
|
{
|
||||||
throw Error(format(
|
throw Error(format(
|
||||||
"the `impossible' happened: expression in path "
|
"the `impossible' happened: expression in path "
|
||||||
"`%1%' appears to have multiple successors "
|
"`%1%' appears to have multiple successors "
|
||||||
"(known `%2%', new `%3%'")
|
"(known `%2%', new `%3%'")
|
||||||
% path1 % known % path2);
|
% srcPath % known % sucPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths revs;
|
Paths revs;
|
||||||
nixDB.queryStrings(txn, dbSuccessorsRev, path2, revs);
|
nixDB.queryStrings(txn, dbSuccessorsRev, sucPath, revs);
|
||||||
revs.push_back(path1);
|
revs.push_back(srcPath);
|
||||||
|
|
||||||
nixDB.setString(txn, dbSuccessors, path1, path2);
|
nixDB.setString(txn, dbSuccessors, srcPath, sucPath);
|
||||||
nixDB.setStrings(txn, dbSuccessorsRev, path2, revs);
|
nixDB.setStrings(txn, dbSuccessorsRev, sucPath, revs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,74 +213,22 @@ void verifyStore()
|
||||||
{
|
{
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
|
|
||||||
/* !!! verify that the result is consistent */
|
Paths paths;
|
||||||
|
nixDB.enumTable(txn, dbValidPaths, paths);
|
||||||
|
|
||||||
#if 0
|
for (Paths::iterator i = paths.begin();
|
||||||
Strings paths;
|
|
||||||
nixDB.enumTable(txn, dbPath2Id, paths);
|
|
||||||
|
|
||||||
for (Strings::iterator i = paths.begin();
|
|
||||||
i != paths.end(); i++)
|
i != paths.end(); i++)
|
||||||
{
|
{
|
||||||
bool erase = true;
|
Path path = *i;
|
||||||
string path = *i;
|
|
||||||
|
|
||||||
if (!pathExists(path)) {
|
if (!pathExists(path)) {
|
||||||
debug(format("path `%1%' disappeared") % path);
|
debug(format("path `%1%' disappeared") % path);
|
||||||
|
nixDB.delPair(txn, dbValidPaths, path);
|
||||||
|
nixDB.delPair(txn, dbSuccessorsRev, path);
|
||||||
|
nixDB.delPair(txn, dbSubstitutesRev, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
string id;
|
|
||||||
if (!nixDB.queryString(txn, dbPath2Id, path, id)) abort();
|
|
||||||
|
|
||||||
Strings idPaths;
|
|
||||||
nixDB.queryStrings(txn, 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) nixDB.delPair(txn, dbPath2Id, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Strings ids;
|
#if 0
|
||||||
nixDB.enumTable(txn, dbId2Paths, ids);
|
|
||||||
|
|
||||||
for (Strings::iterator i = ids.begin();
|
|
||||||
i != ids.end(); i++)
|
|
||||||
{
|
|
||||||
FSId id = parseHash(*i);
|
|
||||||
|
|
||||||
Strings idPaths;
|
|
||||||
nixDB.queryStrings(txn, dbId2Paths, id, idPaths);
|
|
||||||
|
|
||||||
for (Strings::iterator j = idPaths.begin();
|
|
||||||
j != idPaths.end(); )
|
|
||||||
{
|
|
||||||
string id2;
|
|
||||||
if (!nixDB.queryString(txn, 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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
nixDB.setStrings(txn, dbId2Paths, id, idPaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Strings subs;
|
Strings subs;
|
||||||
nixDB.enumTable(txn, dbSubstitutes, subs);
|
nixDB.enumTable(txn, dbSubstitutes, subs);
|
||||||
|
|
||||||
|
@ -308,31 +256,27 @@ void verifyStore()
|
||||||
|
|
||||||
nixDB.setStrings(txn, dbSubstitutes, srcId, subIds);
|
nixDB.setStrings(txn, dbSubstitutes, srcId, subIds);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Strings sucs;
|
Paths sucs;
|
||||||
nixDB.enumTable(txn, dbSuccessors, sucs);
|
nixDB.enumTable(txn, dbSuccessors, sucs);
|
||||||
|
|
||||||
for (Strings::iterator i = sucs.begin();
|
for (Paths::iterator i = sucs.begin(); i != sucs.end(); i++) {
|
||||||
i != sucs.end(); i++)
|
Path srcPath = *i;
|
||||||
{
|
|
||||||
FSId id1 = parseHash(*i);
|
|
||||||
|
|
||||||
string id2;
|
Path sucPath;
|
||||||
if (!nixDB.queryString(txn, dbSuccessors, id1, id2)) abort();
|
if (!nixDB.queryString(txn, dbSuccessors, srcPath, sucPath)) abort();
|
||||||
|
|
||||||
Strings id2Paths;
|
Paths revs;
|
||||||
nixDB.queryStrings(txn, dbId2Paths, id2, id2Paths);
|
nixDB.queryStrings(txn, dbSuccessorsRev, sucPath, revs);
|
||||||
if (id2Paths.size() == 0) {
|
|
||||||
Strings id2Subs;
|
if (find(revs.begin(), revs.end(), srcPath) == revs.end()) {
|
||||||
nixDB.queryStrings(txn, dbSubstitutes, id2, id2Subs);
|
debug(format("reverse successor mapping from `%1%' to `%2%' missing")
|
||||||
if (id2Subs.size() == 0) {
|
% srcPath % sucPath);
|
||||||
debug(format("successor %1% for %2% missing")
|
revs.push_back(srcPath);
|
||||||
% id2 % (string) id1);
|
nixDB.setStrings(txn, dbSuccessorsRev, sucPath, revs);
|
||||||
nixDB.delPair(txn, dbSuccessors, (string) id1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ void copyPath(const Path & src, const Path & dst);
|
||||||
we do it in reverse order, we can get an obstructed build (since to
|
we do it in reverse order, we can get an obstructed build (since to
|
||||||
rebuild the successor, the outputs paths must not exist). */
|
rebuild the successor, the outputs paths must not exist). */
|
||||||
void registerSuccessor(const Transaction & txn,
|
void registerSuccessor(const Transaction & txn,
|
||||||
const Path & path1, const Path & path2);
|
const Path & srcPath, const Path & sucPath);
|
||||||
|
|
||||||
/* Register a substitute. */
|
/* Register a substitute. */
|
||||||
void registerSubstitute(const Path & srcPath, const Path & subPath);
|
void registerSubstitute(const Path & srcPath, const Path & subPath);
|
||||||
|
|
Loading…
Reference in a new issue