* nix-store --verify: repair bad hash fields in the metadata file.

This commit is contained in:
Eelco Dolstra 2008-12-16 13:28:18 +00:00
parent 60ec75048a
commit 8fce03e0ad
2 changed files with 16 additions and 5 deletions

View file

@ -349,7 +349,7 @@ Hash parseHashField(const Path & path, const string & s)
} }
ValidPathInfo LocalStore::queryPathInfo(const Path & path) ValidPathInfo LocalStore::queryPathInfo(const Path & path, bool ignoreErrors)
{ {
ValidPathInfo res; ValidPathInfo res;
res.path = path; res.path = path;
@ -379,7 +379,12 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
} else if (name == "Deriver") { } else if (name == "Deriver") {
res.deriver = value; res.deriver = value;
} else if (name == "Hash") { } else if (name == "Hash") {
try {
res.hash = parseHashField(path, value); res.hash = parseHashField(path, value);
} catch (Error & e) {
if (!ignoreErrors) throw;
printMsg(lvlError, format("cannot parse hash field in `%1%': %2%") % infoFile % e.msg());
}
} else if (name == "Registered-At") { } else if (name == "Registered-At") {
int n = 0; int n = 0;
string2Int(value, n); string2Int(value, n);
@ -997,7 +1002,7 @@ void LocalStore::verifyStore(bool checkContents)
for (PathSet::iterator i = validPaths.begin(); i != validPaths.end(); ++i) { for (PathSet::iterator i = validPaths.begin(); i != validPaths.end(); ++i) {
bool update = false; bool update = false;
ValidPathInfo info = queryPathInfo(*i); ValidPathInfo info = queryPathInfo(*i, true);
/* Check the references: each reference should be valid, and /* Check the references: each reference should be valid, and
it should have a matching referrer. */ it should have a matching referrer. */
@ -1026,7 +1031,11 @@ void LocalStore::verifyStore(bool checkContents)
} }
/* Check the content hash (optionally - slow). */ /* Check the content hash (optionally - slow). */
if (checkContents) { if (info.hash.hashSize == 0) {
printMsg(lvlError, format("re-hashing `%1%'") % *i);
info.hash = hashPath(htSHA256, *i);
update = true;
} else if (checkContents) {
debug(format("checking contents of `%1%'") % *i); debug(format("checking contents of `%1%'") % *i);
Hash current = hashPath(info.hash.type, *i); Hash current = hashPath(info.hash.type, *i);
if (current != info.hash) { if (current != info.hash) {
@ -1052,6 +1061,8 @@ void LocalStore::verifyStore(bool checkContents)
Path from = nixStore + "/" + *i; Path from = nixStore + "/" + *i;
if (validPaths.find(from) == validPaths.end()) { if (validPaths.find(from) == validPaths.end()) {
/* !!! This removes lock files as well. Need to check
whether that's okay. */
printMsg(lvlError, format("removing referrers file for invalid `%1%'") % from); printMsg(lvlError, format("removing referrers file for invalid `%1%'") % from);
Path p = referrersFileFor(from); Path p = referrersFileFor(from);
if (unlink(p.c_str()) == -1) if (unlink(p.c_str()) == -1)

View file

@ -162,7 +162,7 @@ private:
void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false); void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false);
ValidPathInfo queryPathInfo(const Path & path); ValidPathInfo queryPathInfo(const Path & path, bool ignoreErrors = false);
void rewriteReferrers(const Path & path, bool purge, PathSet referrers); void rewriteReferrers(const Path & path, bool purge, PathSet referrers);