about summary refs log tree commit diff
path: root/src/libstore/gc.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-06-18T14·20+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-06-18T14·20+0000
commitd3aa183beb774c20cb77052248cf45e684d134fb (patch)
treedff630ec4a8a0af08added558a1f6b753edfd5dd /src/libstore/gc.cc
parenta8f3b02092fcc08fb25fb327d0188ffc888120bb (diff)
* Garbage collector: option `--max-freed' to stop after at least N
  bytes have been freed, `--max-links' to stop when the Nix store
  directory has fewer than N hard links (the latter being important
  for very large Nix stores on filesystems with a 32000 subdirectories
  limit).

Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r--src/libstore/gc.cc25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 0caf1ce4e6..8f5a1b6e5c 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -439,6 +439,9 @@ Paths topoSortPaths(const PathSet & paths)
 }
 
 
+struct GCLimitReached { };
+
+
 void LocalStore::tryToDelete(const GCOptions & options, GCResults & results, 
     const PathSet & livePaths, const PathSet & tempRootsClosed, PathSet & done, 
     const Path & path)
@@ -512,6 +515,21 @@ void LocalStore::tryToDelete(const GCOptions & options, GCResults & results,
     results.bytesFreed += bytesFreed;
     results.blocksFreed += blocksFreed;
 
+    if (results.bytesFreed > options.maxFreed) {
+        printMsg(lvlInfo, format("deleted more than %1% bytes; stopping") % options.maxFreed);
+        throw GCLimitReached();
+    }
+
+    if (options.maxLinks) {
+        struct stat st;
+        if (stat(nixStore.c_str(), &st) == -1)
+            throw SysError(format("statting `%1%'") % nixStore);
+        if (st.st_nlink < options.maxLinks) {
+            printMsg(lvlInfo, format("link count on the store has dropped below %1%; stopping") % options.maxLinks);
+            throw GCLimitReached();
+        }
+    }
+
 #ifndef __CYGWIN__
     if (fdLock != -1)
         /* Write token to stale (deleted) lock file. */
@@ -650,8 +668,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
         : format("deleting garbage..."));
 
     PathSet done;
-    foreach (PathSet::iterator, i, storePaths)
-        tryToDelete(options, results, livePaths, tempRootsClosed, done, *i);
+    try {
+        foreach (PathSet::iterator, i, storePaths)
+            tryToDelete(options, results, livePaths, tempRootsClosed, done, *i);
+    } catch (GCLimitReached & e) {
+    }
 }