about summary refs log tree commit diff
path: root/src/libstore
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
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')
-rw-r--r--src/libstore/gc.cc25
-rw-r--r--src/libstore/store-api.cc11
-rw-r--r--src/libstore/store-api.hh10
3 files changed, 36 insertions, 10 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 0caf1ce4e627..8f5a1b6e5c99 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) {
+    }
 }
 
  
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 0d516c198d3b..ac31601bef77 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -2,10 +2,21 @@
 #include "globals.hh"
 #include "util.hh"
 
+#include <stdint.h>
+
 
 namespace nix {
 
 
+GCOptions::GCOptions()
+{
+    action = gcDeleteDead;
+    ignoreLiveness = false;
+    maxFreed = ULLONG_MAX;
+    maxLinks = 0;
+}
+
+
 bool StoreAPI::hasSubstitutes(const Path & path)
 {
     PathSet paths = querySubstitutablePaths();
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 760e71adc70b..b2a2dc7a53ec 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -60,16 +60,10 @@ struct GCOptions
     unsigned long long maxFreed;
 
     /* Stop after the number of hard links to the Nix store directory
-       has dropped to at least `maxLinks'. */
+       has dropped below `maxLinks'. */
     unsigned int maxLinks;
 
-    GCOptions() 
-    {
-        action = gcDeleteDead;
-        ignoreLiveness = false;
-        maxFreed = ULLONG_MAX;
-        maxLinks = UINT_MAX;
-    }
+    GCOptions();
 };