summaryrefslogtreecommitdiff
path: root/nix/libstore/gc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nix/libstore/gc.cc')
-rw-r--r--nix/libstore/gc.cc69
1 files changed, 26 insertions, 43 deletions
diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index f90edac1cd..f98e02c1e2 100644
--- a/nix/libstore/gc.cc
+++ b/nix/libstore/gc.cc
@@ -115,7 +115,10 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
% gcRoot % rootsDir);
}
- makeSymlink(gcRoot, storePath);
+ if (baseNameOf(gcRoot) == baseNameOf(storePath))
+ writeFile(gcRoot, "");
+ else
+ makeSymlink(gcRoot, storePath);
}
/* Check that the root can be found by the garbage collector.
@@ -142,11 +145,6 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
}
-/* The file to which we write our temporary roots. */
-static Path fnTempRoots;
-static AutoCloseFD fdTempRoots;
-
-
void LocalStore::addTempRoot(const Path & path)
{
/* Create the temporary roots file for this process. */
@@ -201,27 +199,6 @@ void LocalStore::addTempRoot(const Path & path)
}
-void removeTempRoots()
-{
- if (fdTempRoots != -1) {
- fdTempRoots.close();
- unlink(fnTempRoots.c_str());
- }
-}
-
-
-/* Automatically clean up the temporary roots file when we exit. */
-struct RemoveTempRoots
-{
- ~RemoveTempRoots()
- {
- removeTempRoots();
- }
-};
-
-static RemoveTempRoots autoRemoveTempRoots __attribute__((unused));
-
-
typedef std::shared_ptr<AutoCloseFD> FDPtr;
typedef list<FDPtr> FDs;
@@ -230,11 +207,11 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
{
/* Read the `temproots' directory for per-process temporary root
files. */
- Strings tempRootFiles = readDirectory(
+ DirEntries tempRootFiles = readDirectory(
(format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str());
- foreach (Strings::iterator, i, tempRootFiles) {
- Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % *i).str();
+ for (auto & i : tempRootFiles) {
+ Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str();
debug(format("reading temporary root file `%1%'") % path);
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
@@ -294,19 +271,19 @@ static void foundRoot(StoreAPI & store,
}
-static void findRoots(StoreAPI & store, const Path & path, Roots & roots)
+static void findRoots(StoreAPI & store, const Path & path, unsigned char type, Roots & roots)
{
try {
- struct stat st = lstat(path);
+ if (type == DT_UNKNOWN)
+ type = getFileType(path);
- if (S_ISDIR(st.st_mode)) {
- Strings names = readDirectory(path);
- foreach (Strings::iterator, i, names)
- findRoots(store, path + "/" + *i, roots);
+ if (type == DT_DIR) {
+ for (auto & i : readDirectory(path))
+ findRoots(store, path + "/" + i.name, i.type, roots);
}
- else if (S_ISLNK(st.st_mode)) {
+ else if (type == DT_LNK) {
Path target = readLink(path);
if (isInStore(target))
foundRoot(store, path, target, roots);
@@ -328,6 +305,12 @@ static void findRoots(StoreAPI & store, const Path & path, Roots & roots)
}
}
+ else if (type == DT_REG) {
+ Path storePath = settings.nixStore + "/" + baseNameOf(path);
+ if (store.isValidPath(storePath))
+ roots[path] = storePath;
+ }
+
}
catch (SysError & e) {
@@ -345,9 +328,10 @@ Roots LocalStore::findRoots()
Roots roots;
/* Process direct roots in {gcroots,manifests,profiles}. */
- nix::findRoots(*this, settings.nixStateDir + "/" + gcRootsDir, roots);
- nix::findRoots(*this, settings.nixStateDir + "/manifests", roots);
- nix::findRoots(*this, settings.nixStateDir + "/profiles", roots);
+ nix::findRoots(*this, settings.nixStateDir + "/" + gcRootsDir, DT_UNKNOWN, roots);
+ if (pathExists(settings.nixStateDir + "/manifests"))
+ nix::findRoots(*this, settings.nixStateDir + "/manifests", DT_UNKNOWN, roots);
+ nix::findRoots(*this, settings.nixStateDir + "/profiles", DT_UNKNOWN, roots);
return roots;
}
@@ -449,7 +433,6 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
// if the path was not valid, need to determine the actual
// size.
state.bytesInvalidated += size;
- // Mac OS X cannot rename directories if they are read-only.
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
throw SysError(format("making `%1%' writable") % path);
Path tmp = state.trashDir + "/" + baseNameOf(path);
@@ -649,7 +632,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* After this point the set of roots or temporary roots cannot
increase, since we hold locks on everything. So everything
- that is not reachable from `roots'. */
+ that is not reachable from `roots' is garbage. */
if (state.shouldDelete) {
if (pathExists(state.trashDir)) deleteGarbage(state, state.trashDir);
@@ -741,7 +724,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
}
/* While we're at it, vacuum the database. */
- if (options.action == GCOptions::gcDeleteDead) vacuumDB();
+ //if (options.action == GCOptions::gcDeleteDead) vacuumDB();
}