* 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_DATA_DIR=\"$(datadir)\" \ | ||||||
|  -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ |  -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ | ||||||
|  -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ |  -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ | ||||||
|  |  -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ | ||||||
|  -DNIX_VERSION=\"$(VERSION)\" \ |  -DNIX_VERSION=\"$(VERSION)\" \ | ||||||
|  -I.. ${aterm_include} -I../libutil -I../libstore |  -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)); |     nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR)); | ||||||
|     nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR)); |     nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR)); | ||||||
|     nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db"); |     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
 |     /* Check that the store directory and its parent are not
 | ||||||
|        symlinks. */ |        symlinks. */ | ||||||
|  |  | ||||||
|  | @ -213,14 +213,9 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) | ||||||
|         lockFile(*fd, ltRead, true); |         lockFile(*fd, ltRead, true); | ||||||
| 
 | 
 | ||||||
|         /* Read the entire file. */ |         /* Read the entire file. */ | ||||||
|         struct stat st; |         string contents = readFile(*fd); | ||||||
|         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); |  | ||||||
| 
 | 
 | ||||||
|         /* Extract the roots. */ |         /* Extract the roots. */ | ||||||
|         string contents((char *) buf, st.st_size); |  | ||||||
|         unsigned int pos = 0, end; |         unsigned int pos = 0, end; | ||||||
| 
 | 
 | ||||||
|         while ((end = contents.find((char) 0, pos)) != string::npos) { |         while ((end = contents.find((char) 0, pos)) != string::npos) { | ||||||
|  | @ -311,6 +306,8 @@ void collectGarbage(GCAction action, PathSet & result) | ||||||
| { | { | ||||||
|     result.clear(); |     result.clear(); | ||||||
| 
 | 
 | ||||||
|  |     string gcKeepOutputs = querySetting("gc-keep-outputs", "false"); | ||||||
|  | 
 | ||||||
|     /* Acquire the global GC root.  This prevents
 |     /* Acquire the global GC root.  This prevents
 | ||||||
|        a) New roots from being added. |        a) New roots from being added. | ||||||
|        b) Processes from creating new temporary root files. */ |        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) |     for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i) | ||||||
|         computeFSClosure(canonPath(*i), livePaths); |         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) { |     if (action == gcReturnLive) { | ||||||
|         result = livePaths; |         result = livePaths; | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|  | @ -1,10 +1,14 @@ | ||||||
| #include "globals.hh" | #include "globals.hh" | ||||||
| 
 | 
 | ||||||
|  | #include <map> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| string nixStore = "/UNINIT"; | string nixStore = "/UNINIT"; | ||||||
| string nixDataDir = "/UNINIT"; | string nixDataDir = "/UNINIT"; | ||||||
| string nixLogDir = "/UNINIT"; | string nixLogDir = "/UNINIT"; | ||||||
| string nixStateDir = "/UNINIT"; | string nixStateDir = "/UNINIT"; | ||||||
| string nixDBPath = "/UNINIT"; | string nixDBPath = "/UNINIT"; | ||||||
|  | string nixConfDir = "/UNINIT"; | ||||||
| 
 | 
 | ||||||
| bool keepFailed = false; | bool keepFailed = false; | ||||||
| 
 | 
 | ||||||
|  | @ -17,3 +21,49 @@ Verbosity buildVerbosity = lvlInfo; | ||||||
| unsigned int maxBuildJobs = 1; | unsigned int maxBuildJobs = 1; | ||||||
| 
 | 
 | ||||||
| bool readOnlyMode = false; | 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. */ | /* nixDBPath is the path name of our Berkeley DB environment. */ | ||||||
| extern string nixDBPath; | extern string nixDBPath; | ||||||
| 
 | 
 | ||||||
|  | /* nixConfDir is the directory where configuration files are
 | ||||||
|  |    stored. */ | ||||||
|  | extern string nixConfDir; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* Misc. global flags. */ | /* Misc. global flags. */ | ||||||
| 
 | 
 | ||||||
|  | @ -48,4 +53,7 @@ extern unsigned int maxBuildJobs; | ||||||
| extern bool readOnlyMode; | extern bool readOnlyMode; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | string querySetting(const string & name, const string & def); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #endif /* !__GLOBALS_H */ | #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) | static void _deletePath(const Path & path) | ||||||
| { | { | ||||||
|     checkInterrupt(); |     checkInterrupt(); | ||||||
|  |  | ||||||
|  | @ -90,6 +90,10 @@ bool isLink(const Path & path); | ||||||
|    removed. */ |    removed. */ | ||||||
| Strings readDirectory(const Path & path); | 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
 | /* Delete a path; i.e., in the case of a directory, it is deleted
 | ||||||
|    recursively.  Don't use this at home, kids. */ |    recursively.  Don't use this at home, kids. */ | ||||||
| void deletePath(const Path & path); | void deletePath(const Path & path); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue