From c15f544356dfebf6d08887e73fa156d4e70e2bbc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 20 Jul 2006 12:17:25 +0000 Subject: * Call find-runtime-roots.pl from the garbage collector to prevent running applications etc. from being garbage collected. --- src/libstore/build.cc | 21 +++++---------------- src/libstore/gc.cc | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 16 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 99828a55de7e..c80b3dfe9706 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -12,10 +12,6 @@ #include #include -#ifdef __CYGWIN__ -#include -#endif - #include #include @@ -321,13 +317,6 @@ const char * * strings2CharPtrs(const Strings & ss) } -/* Hack for Cygwin: _exit() doesn't seem to work quite right, since - some Berkeley DB code appears to be called when a child exits - through _exit() (e.g., because execve() failed). So call the - Windows API directly. */ -#ifdef __CYGWIN__ -#define _exit(n) ExitProcess(n) -#endif ////////////////////////////////////////////////////////////////////// @@ -460,9 +449,9 @@ static void killUser(uid_t uid) } catch (exception & e) { cerr << format("build error: %1%\n") % e.what(); - _exit(1); + quickExit(1); } - _exit(0); + quickExit(0); } /* parent */ @@ -944,7 +933,7 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook() } catch (exception & e) { cerr << format("build error: %1%\n") % e.what(); } - _exit(1); + quickExit(1); } /* parent */ @@ -1340,7 +1329,7 @@ void DerivationGoal::startBuilder() } catch (exception & e) { cerr << format("build error: %1%\n") % e.what(); } - _exit(1); + quickExit(1); } @@ -1779,7 +1768,7 @@ void SubstitutionGoal::tryToRun() } catch (exception & e) { cerr << format("substitute error: %1%\n") % e.what(); } - _exit(1); + quickExit(1); } /* parent */ diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 484a5f2beca0..3831de440827 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -316,6 +316,31 @@ static void findRoots(const Path & path, bool recurseSymlinks, } +static void addAdditionalRoots(PathSet & roots) +{ + Path rootFinder = getEnv("NIX_ROOT_FINDER", + "/nix/libexec/nix/find-runtime-roots.pl"); /* !!! */ + + if (rootFinder.empty()) return; + + printMsg(lvlDebug, format("executing `%1%' to find additional roots") % rootFinder); + + string result = runProgram(rootFinder); + + Strings paths = tokenizeString(result, "\n"); + + for (Strings::iterator i = paths.begin(); i != paths.end(); ++i) { + if (isInStore(*i)) { + Path path = toStorePath(*i); + if (roots.find(path) == roots.end()) { + debug(format("found additional root `%1%'") % path); + roots.insert(path); + } + } + } +} + + static void dfsVisit(const PathSet & paths, const Path & path, PathSet & visited, Paths & sorted) { @@ -370,6 +395,12 @@ void collectGarbage(GCAction action, const PathSet & pathsToDelete, if (!ignoreLiveness) findRoots(rootsDir, true, roots); + /* Add additional roots returned by the program specified by the + NIX_ROOT_FINDER environment variable. This is typically used + to add running programs to the set of roots (to prevent them + from being garbage collected). */ + addAdditionalRoots(roots); + if (action == gcReturnRoots) { result = roots; return; -- cgit 1.4.1