* A GC setting `gc-keep-outputs' to specify whether output paths of
derivations should be kept.
This commit is contained in:
		
							parent
							
								
									2e6bf723e4
								
							
						
					
					
						commit
						a37338815d
					
				
					 7 changed files with 102 additions and 7 deletions
				
			
		|  | @ -7,5 +7,6 @@ AM_CXXFLAGS = \ | |||
|  -DNIX_DATA_DIR=\"$(datadir)\" \ | ||||
|  -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ | ||||
|  -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ | ||||
|  -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ | ||||
|  -DNIX_VERSION=\"$(VERSION)\" \ | ||||
|  -I.. ${aterm_include} -I../libutil -I../libstore | ||||
|  |  | |||
|  | @ -106,6 +106,7 @@ static void initAndRun(int argc, char * * argv) | |||
|     nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR)); | ||||
|     nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR)); | ||||
|     nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db"); | ||||
|     nixConfDir = canonPath(getEnv("NIX_CONF_DIR", NIX_CONF_DIR)); | ||||
| 
 | ||||
|     /* Check that the store directory and its parent are not
 | ||||
|        symlinks. */ | ||||
|  |  | |||
|  | @ -213,14 +213,9 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) | |||
|         lockFile(*fd, ltRead, true); | ||||
| 
 | ||||
|         /* Read the entire file. */ | ||||
|         struct stat st; | ||||
|         if (fstat(*fd, &st) == -1) | ||||
|             throw SysError(format("statting `%1%'") % path); | ||||
|         unsigned char buf[st.st_size]; /* !!! stack space */ | ||||
|         readFull(*fd, buf, st.st_size); | ||||
|         string contents = readFile(*fd); | ||||
| 
 | ||||
|         /* Extract the roots. */ | ||||
|         string contents((char *) buf, st.st_size); | ||||
|         unsigned int pos = 0, end; | ||||
| 
 | ||||
|         while ((end = contents.find((char) 0, pos)) != string::npos) { | ||||
|  | @ -310,7 +305,9 @@ static Paths topoSort(const PathSet & paths) | |||
| void collectGarbage(GCAction action, PathSet & result) | ||||
| { | ||||
|     result.clear(); | ||||
|      | ||||
| 
 | ||||
|     string gcKeepOutputs = querySetting("gc-keep-outputs", "false"); | ||||
| 
 | ||||
|     /* Acquire the global GC root.  This prevents
 | ||||
|        a) New roots from being added. | ||||
|        b) Processes from creating new temporary root files. */ | ||||
|  | @ -333,6 +330,19 @@ void collectGarbage(GCAction action, PathSet & result) | |||
|     for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i) | ||||
|         computeFSClosure(canonPath(*i), livePaths); | ||||
| 
 | ||||
|     if (gcKeepOutputs == "true") { | ||||
|         /* Hmz, identical to storePathRequisites in nix-store. */ | ||||
|         for (PathSet::iterator i = livePaths.begin(); | ||||
|              i != livePaths.end(); ++i) | ||||
|             if (isDerivation(*i)) { | ||||
|                 Derivation drv = derivationFromPath(*i); | ||||
|                 for (DerivationOutputs::iterator j = drv.outputs.begin(); | ||||
|                      j != drv.outputs.end(); ++j) | ||||
|                     if (isValidPath(j->second.path)) | ||||
|                         computeFSClosure(j->second.path, livePaths); | ||||
|             } | ||||
|     } | ||||
| 
 | ||||
|     if (action == gcReturnLive) { | ||||
|         result = livePaths; | ||||
|         return; | ||||
|  |  | |||
|  | @ -1,10 +1,14 @@ | |||
| #include "globals.hh" | ||||
| 
 | ||||
| #include <map> | ||||
| 
 | ||||
| 
 | ||||
| string nixStore = "/UNINIT"; | ||||
| string nixDataDir = "/UNINIT"; | ||||
| string nixLogDir = "/UNINIT"; | ||||
| string nixStateDir = "/UNINIT"; | ||||
| string nixDBPath = "/UNINIT"; | ||||
| string nixConfDir = "/UNINIT"; | ||||
| 
 | ||||
| bool keepFailed = false; | ||||
| 
 | ||||
|  | @ -17,3 +21,49 @@ Verbosity buildVerbosity = lvlInfo; | |||
| unsigned int maxBuildJobs = 1; | ||||
| 
 | ||||
| bool readOnlyMode = false; | ||||
| 
 | ||||
| 
 | ||||
| static bool settingsRead = false; | ||||
| 
 | ||||
| static map<string, string> settings; | ||||
| 
 | ||||
| 
 | ||||
| static void readSettings() | ||||
| { | ||||
|     Path settingsFile = (format("%1%/%2%") % nixConfDir % "nix.conf").str(); | ||||
|     if (!pathExists(settingsFile)) return; | ||||
|     string contents = readFile(settingsFile); | ||||
| 
 | ||||
|     unsigned int pos = 0; | ||||
| 
 | ||||
|     while (pos < contents.size()) { | ||||
|         string line; | ||||
|         while (pos < contents.size() && contents[pos] != '\n') | ||||
|             line += contents[pos++]; | ||||
|         pos++; | ||||
| 
 | ||||
|         unsigned int hash = line.find('#'); | ||||
|         if (hash != string::npos) | ||||
|             line = string(line, 0, hash); | ||||
| 
 | ||||
|         if (line.find_first_not_of(" ") == string::npos) continue; | ||||
| 
 | ||||
|         istringstream is(line); | ||||
|         string name, sep, value; | ||||
|         is >> name >> sep >> value; | ||||
|         if (sep != "=" || !is) | ||||
|             throw Error(format("illegal configuration line `%1%'") % line); | ||||
|          | ||||
|         settings[name] = value; | ||||
|     }; | ||||
|      | ||||
|     settingsRead = true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| string querySetting(const string & name, const string & def) | ||||
| { | ||||
|     if (!settingsRead) readSettings(); | ||||
|     map<string, string>::iterator i = settings.find(name); | ||||
|     return i == settings.end() ? def : i->second; | ||||
| } | ||||
|  |  | |||
|  | @ -23,6 +23,11 @@ extern string nixStateDir; | |||
| /* nixDBPath is the path name of our Berkeley DB environment. */ | ||||
| extern string nixDBPath; | ||||
| 
 | ||||
| /* nixConfDir is the directory where configuration files are
 | ||||
|    stored. */ | ||||
| extern string nixConfDir; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* Misc. global flags. */ | ||||
| 
 | ||||
|  | @ -48,4 +53,7 @@ extern unsigned int maxBuildJobs; | |||
| extern bool readOnlyMode; | ||||
| 
 | ||||
| 
 | ||||
| string querySetting(const string & name, const string & def); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* !__GLOBALS_H */ | ||||
|  |  | |||
|  | @ -164,6 +164,27 @@ Strings readDirectory(const Path & path) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| string readFile(int fd) | ||||
| { | ||||
|     struct stat st; | ||||
|     if (fstat(fd, &st) == -1) | ||||
|         throw SysError("statting file"); | ||||
|     unsigned char buf[st.st_size]; /* !!! stack space */ | ||||
|     readFull(fd, buf, st.st_size); | ||||
| 
 | ||||
|     return string((char *) buf, st.st_size); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| string readFile(const Path & path) | ||||
| { | ||||
|     AutoCloseFD fd = open(path.c_str(), O_RDONLY); | ||||
|     if (fd == -1) | ||||
|         throw SysError(format("opening file `%1%'") % path); | ||||
|     return readFile(fd); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void _deletePath(const Path & path) | ||||
| { | ||||
|     checkInterrupt(); | ||||
|  |  | |||
|  | @ -90,6 +90,10 @@ bool isLink(const Path & path); | |||
|    removed. */ | ||||
| Strings readDirectory(const Path & path); | ||||
| 
 | ||||
| /* Read the contents of a file into a string. */ | ||||
| string readFile(int fd); | ||||
| string readFile(const Path & path); | ||||
| 
 | ||||
| /* Delete a path; i.e., in the case of a directory, it is deleted
 | ||||
|    recursively.  Don't use this at home, kids. */ | ||||
| void deletePath(const Path & path); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue