diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-06-18T14·20+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-06-18T14·20+0000 |
commit | d3aa183beb774c20cb77052248cf45e684d134fb (patch) | |
tree | dff630ec4a8a0af08added558a1f6b753edfd5dd /src/libstore/gc.cc | |
parent | a8f3b02092fcc08fb25fb327d0188ffc888120bb (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.cc | 25 |
1 files changed, 23 insertions, 2 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) { + } } |