summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-12-16 13:28:18 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-12-16 13:28:18 +0000
commit8fce03e0adc719930de4f4aebd5dd17b7d59402a (patch)
tree4bdad68e85067b5a7884fdd589b644dec66e91f8 /src
parent60ec75048ae0e0bc72ea2fe47e8b48fcf40a2b86 (diff)
downloadguix-8fce03e0adc719930de4f4aebd5dd17b7d59402a.tar.gz
* nix-store --verify: repair bad hash fields in the metadata file.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/local-store.cc19
-rw-r--r--src/libstore/local-store.hh2
2 files changed, 16 insertions, 5 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 4629402fb1..159f28c918 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -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;
     res.path = path;
@@ -379,7 +379,12 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
         } else if (name == "Deriver") {
             res.deriver = value;
         } else if (name == "Hash") {
-            res.hash = parseHashField(path, value);
+            try {
+                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") {
             int n = 0;
             string2Int(value, n);
@@ -997,7 +1002,7 @@ void LocalStore::verifyStore(bool checkContents)
     
     for (PathSet::iterator i = validPaths.begin(); i != validPaths.end(); ++i) {
         bool update = false;
-        ValidPathInfo info = queryPathInfo(*i);
+        ValidPathInfo info = queryPathInfo(*i, true);
 
         /* Check the references: each reference should be valid, and
            it should have a matching referrer. */
@@ -1026,7 +1031,11 @@ void LocalStore::verifyStore(bool checkContents)
         }
 
         /* 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);
             Hash current = hashPath(info.hash.type, *i);
             if (current != info.hash) {
@@ -1052,6 +1061,8 @@ void LocalStore::verifyStore(bool checkContents)
         Path from = nixStore + "/" + *i;
         
         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);
             Path p = referrersFileFor(from);
             if (unlink(p.c_str()) == -1)
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index f201ddbde9..20a0b45af6 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -162,7 +162,7 @@ private:
 
     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);