aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-10-08 14:58:35 +0200
committerEelco Dolstra <edolstra@gmail.com>2021-10-13 12:12:44 +0200
commit1785ba2980c9dd8274dd4bec5c0e46be02544b7e (patch)
treea1f6ebde142144a4a3a46996e3428b4862f59573 /src/libstore
parentdced45f146e5562b30ad8fb83260019a6f270ae5 (diff)
Simplify
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/gc.cc158
-rw-r--r--src/libstore/local-store.hh4
2 files changed, 81 insertions, 81 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index bb76ee084..969066092 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -479,21 +479,36 @@ struct LocalStore::GCState
};
+void LocalStore::deleteFromStore(GCState & state, std::string_view baseName)
+{
+ Path path = storeDir + "/" + std::string(baseName);
+ Path realPath = realStoreDir + "/" + std::string(baseName);
+
+ printInfo("deleting '%1%'", path);
+
+ state.results.paths.insert(path);
+
+ uint64_t bytesFreed;
+ deletePath(realPath, bytesFreed);
+ state.results.bytesFreed += bytesFreed;
+
+ if (state.results.bytesFreed > state.options.maxFreed) {
+ printInfo("deleted more than %d bytes; stopping", state.options.maxFreed);
+ throw GCLimitReached();
+ }
+}
+
+
bool LocalStore::tryToDelete(
GCState & state,
StorePathSet & visited,
- const Path & path,
+ const StorePath & path,
bool recursive)
{
checkInterrupt();
- auto realPath = realStoreDir + "/" + std::string(baseNameOf(path));
- if (realPath == linksDir) return false;
-
//Activity act(*logger, lvlDebug, format("considering whether to delete '%1%'") % path);
- auto storePath = maybeParseStorePath(path);
-
/* Wake up any client waiting for deletion of this path to
finish. */
Finally releasePending([&]() {
@@ -502,89 +517,66 @@ bool LocalStore::tryToDelete(
state.wakeup.notify_all();
});
- if (storePath) {
+ if (!visited.insert(path).second) return true;
- if (!visited.insert(*storePath).second) return true;
+ if (state.alive.count(path)) return false;
- if (state.alive.count(*storePath)) return false;
+ if (state.dead.count(path)) return true;
- if (state.dead.count(*storePath)) return true;
+ if (state.roots.count(path)) {
+ debug("cannot delete '%s' because it's a root", printStorePath(path));
+ state.alive.insert(path);
+ return false;
+ }
- if (state.roots.count(*storePath)) {
- debug("cannot delete '%s' because it's a root", path);
- state.alive.insert(*storePath);
- return false;
+ if (isValidPath(path)) {
+ StorePathSet incoming;
+
+ /* Don't delete this path if any of its referrers are alive. */
+ queryReferrers(path, incoming);
+
+ /* If keep-derivations is set and this is a derivation, then
+ don't delete the derivation if any of the outputs are
+ alive. */
+ if (state.gcKeepDerivations && path.isDerivation()) {
+ for (auto & [name, maybeOutPath] : queryPartialDerivationOutputMap(path))
+ if (maybeOutPath &&
+ isValidPath(*maybeOutPath) &&
+ queryPathInfo(*maybeOutPath)->deriver == path)
+ incoming.insert(*maybeOutPath);
}
- if (isValidPath(*storePath)) {
- StorePathSet incoming;
-
- /* Don't delete this path if any of its referrers are alive. */
- queryReferrers(*storePath, incoming);
-
- /* If keep-derivations is set and this is a derivation, then
- don't delete the derivation if any of the outputs are alive. */
- if (state.gcKeepDerivations && storePath->isDerivation()) {
- for (auto & [name, maybeOutPath] : queryPartialDerivationOutputMap(*storePath))
- if (maybeOutPath &&
- isValidPath(*maybeOutPath) &&
- queryPathInfo(*maybeOutPath)->deriver == *storePath)
- incoming.insert(*maybeOutPath);
- }
-
- /* If keep-outputs is set, then don't delete this path if there
- are derivers of this path that are not garbage. */
- if (state.gcKeepOutputs) {
- auto derivers = queryValidDerivers(*storePath);
- for (auto & i : derivers)
- incoming.insert(i);
- }
-
- for (auto & i : incoming)
- if (i != *storePath
- && (recursive || state.options.pathsToDelete.count(i))
- && !tryToDelete(state, visited, printStorePath(i), recursive))
- {
- state.alive.insert(*storePath);
- return false;
- }
+ /* If keep-outputs is set, then don't delete this path if
+ there are derivers of this path that are not garbage. */
+ if (state.gcKeepOutputs) {
+ auto derivers = queryValidDerivers(path);
+ for (auto & i : derivers)
+ incoming.insert(i);
}
- {
- auto hashPart = std::string(storePath->hashPart());
- auto shared(state.shared.lock());
- if (shared->tempRoots.count(hashPart))
+ for (auto & i : incoming)
+ if (i != path
+ && (recursive || state.options.pathsToDelete.count(i))
+ && !tryToDelete(state, visited, i, recursive))
+ {
+ state.alive.insert(path);
return false;
- shared->pending = hashPart;
- }
-
- state.dead.insert(*storePath);
-
- if (state.shouldDelete)
- invalidatePathChecked(*storePath);
+ }
}
- if (state.shouldDelete) {
- Path realPath = realStoreDir + "/" + std::string(baseNameOf(path));
-
- struct stat st;
- if (lstat(realPath.c_str(), &st)) {
- if (errno == ENOENT) return true;
- throw SysError("getting status of %1%", realPath);
- }
-
- printInfo("deleting '%1%'", path);
-
- state.results.paths.insert(path);
+ {
+ auto hashPart = std::string(path.hashPart());
+ auto shared(state.shared.lock());
+ if (shared->tempRoots.count(hashPart))
+ return false;
+ shared->pending = hashPart;
+ }
- uint64_t bytesFreed;
- deletePath(realPath, bytesFreed);
- state.results.bytesFreed += bytesFreed;
+ state.dead.insert(path);
- if (state.results.bytesFreed > state.options.maxFreed) {
- printInfo("deleted more than %d bytes; stopping", state.options.maxFreed);
- throw GCLimitReached();
- }
+ if (state.shouldDelete) {
+ invalidatePathChecked(path);
+ deleteFromStore(state, path.to_string());
}
return true;
@@ -777,7 +769,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
for (auto & i : options.pathsToDelete) {
StorePathSet visited;
- if (!tryToDelete(state, visited, printStorePath(i), false))
+ if (!tryToDelete(state, visited, i, false))
throw Error(
"cannot delete path '%1%' since it is still alive. "
"To find out why, use: "
@@ -799,14 +791,20 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* Read the store and delete all paths that are invalid or
unreachable. We don't use readDirectory() here so that
GCing can start faster. */
+ auto linksName = baseNameOf(linksDir);
Paths entries;
struct dirent * dirent;
while (errno = 0, dirent = readdir(dir.get())) {
checkInterrupt();
string name = dirent->d_name;
- if (name == "." || name == "..") continue;
- StorePathSet visited;
- tryToDelete(state, visited, storeDir + "/" + name, true);
+ if (name == "." || name == ".." || name == linksName) continue;
+
+ if (auto storePath = maybeParseStorePath(storeDir + "/" + name)) {
+ StorePathSet visited;
+ tryToDelete(state, visited, *storePath, true);
+ } else
+ deleteFromStore(state, name);
+
}
} catch (GCLimitReached & e) {
}
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 12c057ec3..08bbc1a7d 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -243,9 +243,11 @@ private:
bool tryToDelete(
GCState & state,
StorePathSet & visited,
- const Path & path,
+ const StorePath & path,
bool recursive);
+ void deleteFromStore(GCState & state, std::string_view baseName);
+
void findRoots(const Path & path, unsigned char type, Roots & roots);
void findRootsNoTemp(Roots & roots, bool censor);