1 : #include "normalise.hh"
2 : #include "globals.hh"
3 :
4 :
5 : #include <sys/types.h>
6 : #include <sys/stat.h>
7 : #include <unistd.h>
8 :
9 :
10 : void followLivePaths(Path nePath, PathSet & live)
11 0 : {
12 : /* Just to be sure, canonicalise the path. It is important to do
13 : this here and in findDeadPath() to ensure that a live path is
14 : not mistaken for a dead path due to some non-canonical
15 : representation. */
16 0 : nePath = canonPath(nePath);
17 :
18 0 : if (live.find(nePath) != live.end()) return;
19 0 : live.insert(nePath);
20 :
21 0 : startNest(nest, lvlDebug, format("following `%1%'") % nePath);
22 0 : assertStorePath(nePath);
23 :
24 0 : if (isValidPath(nePath)) {
25 :
26 : /* !!! should make sure that no substitutes are used */
27 0 : StoreExpr ne = storeExprFromPath(nePath);
28 :
29 : /* !!! painfully similar to requisitesWorker() */
30 0 : if (ne.type == StoreExpr::neClosure)
31 0 : for (ClosureElems::iterator i = ne.closure.elems.begin();
32 : i != ne.closure.elems.end(); ++i)
33 : {
34 0 : Path p = canonPath(i->first);
35 0 : if (live.find(p) == live.end()) {
36 0 : debug(format("found live `%1%'") % p);
37 0 : assertStorePath(p);
38 0 : live.insert(p);
39 : }
40 : }
41 :
42 0 : else if (ne.type == StoreExpr::neDerivation)
43 0 : for (PathSet::iterator i = ne.derivation.inputs.begin();
44 : i != ne.derivation.inputs.end(); ++i)
45 0 : followLivePaths(*i, live);
46 :
47 0 : else abort();
48 :
49 : }
50 :
51 0 : Path nfPath;
52 0 : if (querySuccessor(nePath, nfPath))
53 0 : followLivePaths(nfPath, live);
54 : }
55 :
56 :
57 : PathSet findLivePaths(const Paths & roots)
58 0 : {
59 0 : PathSet live;
60 :
61 0 : startNest(nest, lvlDebug, "finding live paths");
62 :
63 0 : for (Paths::const_iterator i = roots.begin(); i != roots.end(); ++i)
64 0 : followLivePaths(*i, live);
65 :
66 0 : return live;
67 : }
68 :
69 :
70 : PathSet findDeadPaths(const PathSet & live, time_t minAge)
71 0 : {
72 0 : PathSet dead;
73 :
74 0 : startNest(nest, lvlDebug, "finding dead paths");
75 :
76 0 : time_t now = time(0);
77 :
78 0 : Strings storeNames = readDirectory(nixStore);
79 :
80 0 : for (Strings::iterator i = storeNames.begin(); i != storeNames.end(); ++i) {
81 0 : Path p = canonPath(nixStore + "/" + *i);
82 :
83 0 : if (minAge > 0) {
84 0 : struct stat st;
85 0 : if (lstat(p.c_str(), &st) != 0)
86 0 : throw SysError(format("obtaining information about `%1%'") % p);
87 0 : if (st.st_atime + minAge >= now) continue;
88 : }
89 :
90 0 : if (live.find(p) == live.end()) {
91 0 : debug(format("dead path `%1%'") % p);
92 0 : dead.insert(p);
93 : } else
94 0 : debug(format("live path `%1%'") % p);
95 : }
96 :
97 0 : return dead;
98 : }
|