* Added an option "fsync-metadata" to fsync() changes to
/nix/var/nix/db. * Removed the function writeStringToFile since it does (almost) the same thing as writeFile.
This commit is contained in:
		
							parent
							
								
									ad529fb89f
								
							
						
					
					
						commit
						07ffdc2862
					
				
					 6 changed files with 37 additions and 28 deletions
				
			
		|  | @ -235,6 +235,16 @@ build-use-chroot = /dev /proc /bin</programlisting> | ||||||
|   </varlistentry> |   </varlistentry> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |   <varlistentry><term><literal>fsync-metadata</literal></term> | ||||||
|  | 
 | ||||||
|  |     <listitem><para>If set to <literal>true</literal>, changes to the | ||||||
|  |     Nix store metadata (in <filename>/nix/var/nix/db</filename>) are | ||||||
|  |     synchronously flushed to disk.  This improves robustness in case | ||||||
|  |     of system crashes, but reduces performance.  The default is | ||||||
|  |     <literal>false</literal>.</para></listitem> | ||||||
|  | 
 | ||||||
|  |   </varlistentry> | ||||||
|  |      | ||||||
| </variablelist> | </variablelist> | ||||||
| 
 | 
 | ||||||
| </para> | </para> | ||||||
|  |  | ||||||
|  | @ -1318,18 +1318,18 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook() | ||||||
|         string s; |         string s; | ||||||
|         foreach (PathSet::iterator, i, allInputs) s += *i + "\n"; |         foreach (PathSet::iterator, i, allInputs) s += *i + "\n"; | ||||||
|          |          | ||||||
|         writeStringToFile(inputListFN, s); |         writeFile(inputListFN, s); | ||||||
| 
 | 
 | ||||||
|         /* The `outputs' file lists all outputs that have to be copied
 |         /* The `outputs' file lists all outputs that have to be copied
 | ||||||
|            from the remote system. */ |            from the remote system. */ | ||||||
|         s = ""; |         s = ""; | ||||||
|         foreach (DerivationOutputs::iterator, i, drv.outputs) |         foreach (DerivationOutputs::iterator, i, drv.outputs) | ||||||
|             s += i->second.path + "\n"; |             s += i->second.path + "\n"; | ||||||
|         writeStringToFile(outputListFN, s); |         writeFile(outputListFN, s); | ||||||
| 
 | 
 | ||||||
|         /* The `references' file has exactly the format accepted by
 |         /* The `references' file has exactly the format accepted by
 | ||||||
|            `nix-store --register-validity'. */ |            `nix-store --register-validity'. */ | ||||||
|         writeStringToFile(referencesFN, |         writeFile(referencesFN, | ||||||
|             makeValidityRegistration(allInputs, true, false)); |             makeValidityRegistration(allInputs, true, false)); | ||||||
| 
 | 
 | ||||||
|         /* Tell the hook to proceed. */ |         /* Tell the hook to proceed. */ | ||||||
|  | @ -1493,7 +1493,7 @@ void DerivationGoal::startBuilder() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Write closure info to `fileName'. */ |         /* Write closure info to `fileName'. */ | ||||||
|         writeStringToFile(tmpDir + "/" + fileName, |         writeFile(tmpDir + "/" + fileName, | ||||||
|             makeValidityRegistration(paths, false, false)); |             makeValidityRegistration(paths, false, false)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1570,7 +1570,7 @@ void DerivationGoal::startBuilder() | ||||||
|            support Samba-in-QEMU. */ |            support Samba-in-QEMU. */ | ||||||
|         createDirs(chrootRootDir + "/etc"); |         createDirs(chrootRootDir + "/etc"); | ||||||
| 
 | 
 | ||||||
|         writeStringToFile(chrootRootDir + "/etc/passwd", |         writeFile(chrootRootDir + "/etc/passwd", | ||||||
|             (format( |             (format( | ||||||
|                 "nixbld:x:%1%:65534:Nix build user:/:/noshell\n" |                 "nixbld:x:%1%:65534:Nix build user:/:/noshell\n" | ||||||
|                 "nobody:x:65534:65534:Nobody:/:/noshell\n") |                 "nobody:x:65534:65534:Nobody:/:/noshell\n") | ||||||
|  |  | ||||||
|  | @ -89,6 +89,8 @@ LocalStore::LocalStore() | ||||||
|     } |     } | ||||||
|     if (curSchema == 1) throw Error("your Nix store is no longer supported"); |     if (curSchema == 1) throw Error("your Nix store is no longer supported"); | ||||||
|     if (curSchema < nixSchemaVersion) upgradeStore12(); |     if (curSchema < nixSchemaVersion) upgradeStore12(); | ||||||
|  | 
 | ||||||
|  |     doFsync = queryBoolSetting("fsync-metadata", false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -222,7 +224,7 @@ static Path tmpFileForAtomicUpdate(const Path & path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void appendReferrer(const Path & from, const Path & to, bool lock) | void LocalStore::appendReferrer(const Path & from, const Path & to, bool lock) | ||||||
| { | { | ||||||
|     Path referrersFile = referrersFileFor(from); |     Path referrersFile = referrersFileFor(from); | ||||||
|      |      | ||||||
|  | @ -237,6 +239,8 @@ static void appendReferrer(const Path & from, const Path & to, bool lock) | ||||||
|      |      | ||||||
|     string s = " " + to; |     string s = " " + to; | ||||||
|     writeFull(fd, (const unsigned char *) s.c_str(), s.size()); |     writeFull(fd, (const unsigned char *) s.c_str(), s.size()); | ||||||
|  | 
 | ||||||
|  |     if (doFsync) fdatasync(fd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -267,6 +271,8 @@ void LocalStore::rewriteReferrers(const Path & path, bool purge, PathSet referre | ||||||
|      |      | ||||||
|     writeFull(fd, (const unsigned char *) s.c_str(), s.size()); |     writeFull(fd, (const unsigned char *) s.c_str(), s.size()); | ||||||
| 
 | 
 | ||||||
|  |     if (doFsync) fdatasync(fd); | ||||||
|  |      | ||||||
|     fd.close(); /* for Windows; can't rename open file */ |     fd.close(); /* for Windows; can't rename open file */ | ||||||
| 
 | 
 | ||||||
|     if (rename(tmpFile.c_str(), referrersFile.c_str()) == -1) |     if (rename(tmpFile.c_str(), referrersFile.c_str()) == -1) | ||||||
|  | @ -347,7 +353,7 @@ void LocalStore::registerValidPath(const ValidPathInfo & info, bool ignoreValidi | ||||||
| 
 | 
 | ||||||
|     /* Atomically rewrite the info file. */ |     /* Atomically rewrite the info file. */ | ||||||
|     Path tmpFile = tmpFileForAtomicUpdate(infoFile); |     Path tmpFile = tmpFileForAtomicUpdate(infoFile); | ||||||
|     writeFile(tmpFile, s); |     writeFile(tmpFile, s, doFsync); | ||||||
|     if (rename(tmpFile.c_str(), infoFile.c_str()) == -1) |     if (rename(tmpFile.c_str(), infoFile.c_str()) == -1) | ||||||
|         throw SysError(format("cannot rename `%1%' to `%2%'") % tmpFile % infoFile); |         throw SysError(format("cannot rename `%1%' to `%2%'") % tmpFile % infoFile); | ||||||
| 
 | 
 | ||||||
|  | @ -737,7 +743,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name, | ||||||
|                 StringSource source(dump); |                 StringSource source(dump); | ||||||
|                 restorePath(dstPath, source); |                 restorePath(dstPath, source); | ||||||
|             } else |             } else | ||||||
|                 writeStringToFile(dstPath, dump); |                 writeFile(dstPath, dump); | ||||||
| 
 | 
 | ||||||
|             canonicalisePathMetaData(dstPath); |             canonicalisePathMetaData(dstPath); | ||||||
| 
 | 
 | ||||||
|  | @ -792,7 +798,7 @@ Path LocalStore::addTextToStore(const string & name, const string & s, | ||||||
| 
 | 
 | ||||||
|             if (pathExists(dstPath)) deletePathWrapped(dstPath); |             if (pathExists(dstPath)) deletePathWrapped(dstPath); | ||||||
| 
 | 
 | ||||||
|             writeStringToFile(dstPath, s); |             writeFile(dstPath, s); | ||||||
| 
 | 
 | ||||||
|             canonicalisePathMetaData(dstPath); |             canonicalisePathMetaData(dstPath); | ||||||
|              |              | ||||||
|  | @ -871,7 +877,7 @@ void LocalStore::exportPath(const Path & path, bool sign, | ||||||
|         Path tmpDir = createTempDir(); |         Path tmpDir = createTempDir(); | ||||||
|         AutoDelete delTmp(tmpDir); |         AutoDelete delTmp(tmpDir); | ||||||
|         Path hashFile = tmpDir + "/hash"; |         Path hashFile = tmpDir + "/hash"; | ||||||
|         writeStringToFile(hashFile, printHash(hash)); |         writeFile(hashFile, printHash(hash)); | ||||||
| 
 | 
 | ||||||
|         Path secretKey = nixConfDir + "/signing-key.sec"; |         Path secretKey = nixConfDir + "/signing-key.sec"; | ||||||
|         checkSecrecy(secretKey); |         checkSecrecy(secretKey); | ||||||
|  | @ -947,7 +953,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) | ||||||
| 
 | 
 | ||||||
|         if (requireSignature) { |         if (requireSignature) { | ||||||
|             Path sigFile = tmpDir + "/sig"; |             Path sigFile = tmpDir + "/sig"; | ||||||
|             writeStringToFile(sigFile, signature); |             writeFile(sigFile, signature); | ||||||
| 
 | 
 | ||||||
|             Strings args; |             Strings args; | ||||||
|             args.push_back("rsautl"); |             args.push_back("rsautl"); | ||||||
|  |  | ||||||
|  | @ -158,12 +158,17 @@ private: | ||||||
|     /* Store paths for which the referrers file must be purged. */ |     /* Store paths for which the referrers file must be purged. */ | ||||||
|     PathSet delayedUpdates; |     PathSet delayedUpdates; | ||||||
| 
 | 
 | ||||||
|  |     /* Whether to do an fsync() after writing Nix metadata. */ | ||||||
|  |     bool doFsync; | ||||||
|  | 
 | ||||||
|     int getSchema(); |     int getSchema(); | ||||||
| 
 | 
 | ||||||
|     void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false); |     void registerValidPath(const ValidPathInfo & info, bool ignoreValidity = false); | ||||||
| 
 | 
 | ||||||
|     ValidPathInfo queryPathInfo(const Path & path, bool ignoreErrors = false); |     ValidPathInfo queryPathInfo(const Path & path, bool ignoreErrors = false); | ||||||
| 
 | 
 | ||||||
|  |     void appendReferrer(const Path & from, const Path & to, bool lock); | ||||||
|  |      | ||||||
|     void rewriteReferrers(const Path & path, bool purge, PathSet referrers); |     void rewriteReferrers(const Path & path, bool purge, PathSet referrers); | ||||||
| 
 | 
 | ||||||
|     void flushDelayedUpdates(); |     void flushDelayedUpdates(); | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ | ||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
|  | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| #include "util.hh" | #include "util.hh" | ||||||
| 
 | 
 | ||||||
|  | @ -220,12 +221,13 @@ string readFile(const Path & path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void writeFile(const Path & path, const string & s) | void writeFile(const Path & path, const string & s, bool doFsync) | ||||||
| { | { | ||||||
|     AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); |     AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); | ||||||
|     if (fd == -1) |     if (fd == -1) | ||||||
|         throw SysError(format("opening file `%1%'") % path); |         throw SysError(format("opening file `%1%'") % path); | ||||||
|     writeFull(fd, (unsigned char *) s.c_str(), s.size()); |     writeFull(fd, (unsigned char *) s.c_str(), s.size()); | ||||||
|  |     if (doFsync) fdatasync(fd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -413,16 +415,6 @@ Paths createDirs(const Path & path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void writeStringToFile(const Path & path, const string & s) |  | ||||||
| { |  | ||||||
|     AutoCloseFD fd(open(path.c_str(), |  | ||||||
|         O_CREAT | O_EXCL | O_WRONLY, 0666)); |  | ||||||
|     if (fd == -1) |  | ||||||
|         throw SysError(format("creating file `%1%'") % path); |  | ||||||
|     writeFull(fd, (unsigned char *) s.c_str(), s.size()); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| LogType logType = ltPretty; | LogType logType = ltPretty; | ||||||
| Verbosity verbosity = lvlInfo; | Verbosity verbosity = lvlInfo; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ string readFile(int fd); | ||||||
| string readFile(const Path & path); | string readFile(const Path & path); | ||||||
| 
 | 
 | ||||||
| /* Write a string to a file. */ | /* Write a string to a file. */ | ||||||
| void writeFile(const Path & path, const string & s); | void writeFile(const Path & path, const string & s, bool doFsync = false); | ||||||
| 
 | 
 | ||||||
| /* Read a line from a file descriptor. */ | /* Read a line from a file descriptor. */ | ||||||
| string readLine(int fd); | string readLine(int fd); | ||||||
|  | @ -93,10 +93,6 @@ Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", | ||||||
|    list of created directories, in order of creation. */ |    list of created directories, in order of creation. */ | ||||||
| Paths createDirs(const Path & path); | Paths createDirs(const Path & path); | ||||||
| 
 | 
 | ||||||
| /* Create a file and write the given text to it.  The file is written
 |  | ||||||
|    in binary mode (i.e., no end-of-line conversions).  The path should |  | ||||||
|    not already exist. */ |  | ||||||
| void writeStringToFile(const Path & path, const string & s); |  | ||||||
| 
 | 
 | ||||||
| template<class T, class A> | template<class T, class A> | ||||||
| T singleton(const A & a) | T singleton(const A & a) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue