Skip to content

Commit

Permalink
* Garbage collector: option `--max-freed' to stop after at least N
Browse files Browse the repository at this point in the history
  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).
  • Loading branch information
edolstra committed Jun 18, 2008
1 parent a8f3b02 commit d3aa183
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/libmain/shared.cc
Expand Up @@ -58,7 +58,7 @@ static void setLogType(string lt)
}


static unsigned int getIntArg(const string & opt,
unsigned int getIntArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end)
{
++i;
Expand Down
3 changes: 3 additions & 0 deletions src/libmain/shared.hh
Expand Up @@ -26,6 +26,9 @@ namespace nix {
Path makeRootName(const Path & gcRoot, int & counter);
void printGCWarning();

unsigned int getIntArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end);

/* Whether we're running setuid. */
extern bool setuidMode;

Expand Down
25 changes: 23 additions & 2 deletions src/libstore/gc.cc
Expand Up @@ -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)
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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) {
}
}


Expand Down
11 changes: 11 additions & 0 deletions src/libstore/store-api.cc
Expand Up @@ -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();
Expand Down
10 changes: 2 additions & 8 deletions src/libstore/store-api.hh
Expand Up @@ -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();
};


Expand Down
8 changes: 7 additions & 1 deletion src/nix-store/nix-store.cc
Expand Up @@ -528,6 +528,8 @@ static void opGC(Strings opFlags, Strings opArgs)
else if (*i == "--print-live") options.action = GCOptions::gcReturnLive;
else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead;
else if (*i == "--delete") options.action = GCOptions::gcDeleteDead;
else if (*i == "--max-freed") options.maxFreed = getIntArg(*i, i, opFlags.end());
else if (*i == "--max-links") options.maxLinks = getIntArg(*i, i, opFlags.end());
else throw UsageError(format("bad sub-operation `%1%' in GC") % *i);

PrintFreed freed(
Expand Down Expand Up @@ -744,8 +746,12 @@ void run(Strings args)
}
else if (arg == "--indirect")
indirectRoot = true;
else if (arg[0] == '-')
else if (arg[0] == '-') {
opFlags.push_back(arg);
if (arg == "--max-freed" || arg == "--max-links") { /* !!! hack */
if (i != args.end()) opFlags.push_back(*i++);
}
}
else
opArgs.push_back(arg);

Expand Down

0 comments on commit d3aa183

Please sign in to comment.