* 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
|
@ -233,7 +233,17 @@ build-use-chroot = /dev /proc /bin</programlisting>
|
||||||
<filename>configure</filename> at build time.</para></listitem>
|
<filename>configure</filename> at build time.</para></listitem>
|
||||||
|
|
||||||
</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>
|
||||||
|
|
||||||
|
|
|
@ -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…
Reference in a new issue