aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/optimise-store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/optimise-store.cc')
-rw-r--r--src/libstore/optimise-store.cc31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index d95e54af1..c93d0706d 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -88,7 +88,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
- const Path & path, InodeHash & inodeHash)
+ const Path & path, InodeHash & inodeHash, bool repair)
{
checkInterrupt();
@@ -110,7 +110,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
if (S_ISDIR(st.st_mode)) {
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
for (auto & i : names)
- optimisePath_(act, stats, path + "/" + i, inodeHash);
+ optimisePath_(act, stats, path + "/" + i, inodeHash, repair);
return;
}
@@ -151,7 +151,20 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
/* Check if this is a known hash. */
Path linkPath = linksDir + "/" + hash.to_string(Base32, false);
- retry:
+ /* Maybe delete the link, if it has been corrupted. */
+ if (pathExists(linkPath)) {
+ auto stLink = lstat(linkPath);
+ if (st.st_size != stLink.st_size
+ || (repair && hash != hashPath(htSHA256, linkPath).first))
+ {
+ // XXX: Consider overwriting linkPath with our valid version.
+ warn("removing corrupted link '%s'", linkPath);
+ warn("There may be more corrupted paths."
+ "\nYou should run `nix-store --verify --check-contents --repair` to fix them all");
+ unlink(linkPath.c_str());
+ }
+ }
+
if (!pathExists(linkPath)) {
/* Nope, create a hard link in the links directory. */
if (link(path.c_str(), linkPath.c_str()) == 0) {
@@ -187,12 +200,6 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
return;
}
- if (st.st_size != stLink.st_size) {
- warn("removing corrupted link '%s'", linkPath);
- unlink(linkPath.c_str());
- goto retry;
- }
-
printMsg(lvlTalkative, format("linking '%1%' to '%2%'") % path % linkPath);
/* Make the containing directory writable, but only if it's not
@@ -260,7 +267,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
{
Activity act(*logger, lvlTalkative, actUnknown, fmt("optimising path '%s'", printStorePath(i)));
- optimisePath_(&act, stats, realStoreDir + "/" + std::string(i.to_string()), inodeHash);
+ optimisePath_(&act, stats, realStoreDir + "/" + std::string(i.to_string()), inodeHash, false);
}
done++;
act.progress(done, paths.size());
@@ -278,12 +285,12 @@ void LocalStore::optimiseStore()
stats.filesLinked);
}
-void LocalStore::optimisePath(const Path & path)
+void LocalStore::optimisePath(const Path & path, bool repair)
{
OptimiseStats stats;
InodeHash inodeHash;
- if (settings.autoOptimiseStore) optimisePath_(nullptr, stats, path, inodeHash);
+ if (settings.autoOptimiseStore) optimisePath_(nullptr, stats, path, inodeHash, repair);
}