diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/gc.cc | 17 | ||||
-rw-r--r-- | src/libstore/gc.hh | 6 | ||||
-rw-r--r-- | src/nix-store/main.cc | 25 |
3 files changed, 35 insertions, 13 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index aed7c2294b04..9af957693f0c 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -2,6 +2,11 @@ #include "globals.hh" +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + + void followLivePaths(Path nePath, PathSet & live) { /* Just to be sure, canonicalise the path. It is important to do @@ -62,16 +67,26 @@ PathSet findLivePaths(const Paths & roots) } -PathSet findDeadPaths(const PathSet & live) +PathSet findDeadPaths(const PathSet & live, time_t minAge) { PathSet dead; startNest(nest, lvlDebug, "finding dead paths"); + time_t now = time(0); + Strings storeNames = readDirectory(nixStore); for (Strings::iterator i = storeNames.begin(); i != storeNames.end(); ++i) { Path p = canonPath(nixStore + "/" + *i); + + if (minAge > 0) { + struct stat st; + if (lstat(p.c_str(), &st) != 0) + throw SysError(format("obtaining information about `%1%'") % p); + if (st.st_atime + minAge >= now) continue; + } + if (live.find(p) == live.end()) { debug(format("dead path `%1%'") % p); dead.insert(p); diff --git a/src/libstore/gc.hh b/src/libstore/gc.hh index 997057ba9b7b..1ada419da439 100644 --- a/src/libstore/gc.hh +++ b/src/libstore/gc.hh @@ -17,8 +17,10 @@ PathSet findLivePaths(const Paths & roots); /* Given a set of "live" store paths, determine the set of "dead" store paths (which are simply all store paths that are not in the - live set). */ -PathSet findDeadPaths(const PathSet & live); + live set). The value `minAge' specifies the minimum age in seconds + for an unreachable file to be considered dead (0 meaning that any + unreachable file is dead). */ +PathSet findDeadPaths(const PathSet & live, time_t minAge); #endif /* !__GC_H */ diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index 7bc8565d293d..e9948c7cf8ac 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -212,17 +212,22 @@ static void opIsValid(Strings opFlags, Strings opArgs) static void opGC(Strings opFlags, Strings opArgs) { - if (opFlags.size() != 1) throw UsageError("missing flag"); - if (!opArgs.empty()) - throw UsageError("no arguments expected"); - /* Do what? */ - string flag = opFlags.front(); enum { soPrintLive, soPrintDead, soDelete } subOp; - if (flag == "--print-live") subOp = soPrintLive; - else if (flag == "--print-dead") subOp = soPrintDead; - else if (flag == "--delete") subOp = soDelete; - else throw UsageError(format("bad sub-operation `%1%' in GC") % flag); + time_t minAge = 0; + for (Strings::iterator i = opFlags.begin(); + i != opFlags.end(); ++i) + if (*i == "--print-live") subOp = soPrintLive; + else if (*i == "--print-dead") subOp = soPrintDead; + else if (*i == "--delete") subOp = soDelete; + else if (*i == "--min-age") { + if (opArgs.size() == 0) + throw UsageError("`--min-age' requires an argument"); + istringstream st(opArgs.front()); + st >> minAge; + if (!st) throw Error("number expected"); + } + else throw UsageError(format("bad sub-operation `%1%' in GC") % *i); Paths roots; while (1) { @@ -240,7 +245,7 @@ static void opGC(Strings opFlags, Strings opArgs) return; } - PathSet dead = findDeadPaths(live); + PathSet dead = findDeadPaths(live, minAge * 3600); if (subOp == soPrintDead) { for (PathSet::iterator i = dead.begin(); i != dead.end(); ++i) |