aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstore/gc.cc17
-rw-r--r--src/libstore/gc.hh6
-rw-r--r--src/nix-store/main.cc25
3 files changed, 35 insertions, 13 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index aed7c2294..9af957693 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 997057ba9..1ada419da 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 7bc8565d2..e9948c7cf 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)