aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-11-26 20:21:48 +0100
committerEelco Dolstra <edolstra@gmail.com>2019-11-26 20:21:48 +0100
commit96e1c39bb71327f49a7955f945dd95aec66f5ef1 (patch)
tree9740c0ed600ce7214990d00b023c269eff6faad7 /src
parent872740cf60ca29820a25e61882a192f6abe9d68e (diff)
parent3e2c77d001a31952e62bfbb825bc7e034678ae12 (diff)
Merge branch 'repair-bad-links' of https://github.com/chkno/nix
Diffstat (limited to 'src')
-rw-r--r--src/libstore/local-store.cc30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 7d127840a..0d44665b0 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -1241,7 +1241,35 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
/* Optionally, check the content hashes (slow). */
if (checkContents) {
- printInfo("checking hashes...");
+
+ printInfo("checking link hashes...");
+
+ AutoCloseDir dir(opendir(linksDir.c_str()));
+ if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
+
+ struct dirent * dirent;
+ while (errno = 0, dirent = readdir(dir.get())) { /* sic */
+ checkInterrupt();
+ if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue;
+ Path linkPath = linksDir + "/" + dirent->d_name;
+ string hash = hashPath(htSHA256, linkPath).first.to_string(Base32, false);
+ if (hash != dirent->d_name) {
+ printError(format("link '%1%' was modified! "
+ "expected hash '%2%', got '%3%'")
+ % linkPath % dirent->d_name % hash);
+ if (repair) {
+ if (unlink(linkPath.c_str()) == 0)
+ printError(format("Removed link '%1%'") % linkPath);
+ else
+ throw SysError(format("removing corrupt link '%1%'") % linkPath);
+ } else {
+ errors = true;
+ }
+ }
+ }
+ if (errno) throw SysError(format("reading directory '%1%'") % linksDir);
+
+ printInfo("checking store hashes...");
Hash nullHash(htSHA256);