aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-07-30 19:55:41 -0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-07-30 19:55:41 -0400
commit97421eb5ecde86b75441094fda017b12b5eca2a6 (patch)
tree97ab7442b5bf13363320b4facb50d2f3e384d8ed
parentd50d7a287416da2086b0b24f9d998eabb24c1734 (diff)
Refactor settings processing
Put all Nix configuration flags in a Settings object.
-rw-r--r--perl/lib/Nix/Store.xs2
-rw-r--r--src/libexpr/eval.cc4
-rw-r--r--src/libexpr/primops.cc6
-rw-r--r--src/libmain/shared.cc47
-rw-r--r--src/libstore/build.cc176
-rw-r--r--src/libstore/derivations.cc22
-rw-r--r--src/libstore/gc.cc78
-rw-r--r--src/libstore/globals.cc201
-rw-r--r--src/libstore/globals.hh221
-rw-r--r--src/libstore/local-store.cc64
-rw-r--r--src/libstore/local-store.hh49
-rw-r--r--src/libstore/misc.cc24
-rw-r--r--src/libstore/optimise-store.cc28
-rw-r--r--src/libstore/remote-store.cc24
-rw-r--r--src/libstore/store-api.cc16
-rw-r--r--src/nix-env/nix-env.cc20
-rw-r--r--src/nix-instantiate/nix-instantiate.cc4
-rw-r--r--src/nix-store/nix-store.cc70
-rw-r--r--src/nix-worker/nix-worker.cc32
19 files changed, 566 insertions, 522 deletions
diff --git a/perl/lib/Nix/Store.xs b/perl/lib/Nix/Store.xs
index 76de674e6..00311aa8f 100644
--- a/perl/lib/Nix/Store.xs
+++ b/perl/lib/Nix/Store.xs
@@ -19,7 +19,7 @@ void doInit()
{
if (!store) {
try {
- setDefaultsFromEnvironment();
+ settings.processEnvironment();
store = openStore();
} catch (Error & e) {
croak(e.what());
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index cf7c62ad2..74f7560fe 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -179,7 +179,7 @@ EvalState::EvalState()
searchPathInsertionPoint = searchPath.end();
Strings paths = tokenizeString(getEnv("NIX_PATH", ""), ":");
foreach (Strings::iterator, i, paths) addToSearchPath(*i);
- addToSearchPath("nix=" + nixDataDir + "/nix/corepkgs");
+ addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs");
searchPathInsertionPoint = searchPath.begin();
createBaseEnv();
@@ -1058,7 +1058,7 @@ string EvalState::coerceToString(Value & v, PathSet & context,
if (srcToStore[path] != "")
dstPath = srcToStore[path];
else {
- dstPath = readOnlyMode
+ dstPath = settings.readOnlyMode
? computeStorePathForPath(path).first
: store->addToStore(path);
srcToStore[path] = dstPath;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 5c011c43e..7258c4cc0 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -623,7 +623,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v)
refs.insert(path);
}
- Path storePath = readOnlyMode
+ Path storePath = settings.readOnlyMode
? computeStorePathForText(name, contents, refs)
: store->addTextToStore(name, contents, refs);
@@ -687,7 +687,7 @@ static void prim_filterSource(EvalState & state, Value * * args, Value & v)
FilterFromExpr filter(state, *args[0]);
- Path dstPath = readOnlyMode
+ Path dstPath = settings.readOnlyMode
? computeStorePathForPath(path, true, htSHA256, filter).first
: store->addToStore(path, true, htSHA256, filter);
@@ -1079,7 +1079,7 @@ void EvalState::createBaseEnv()
mkInt(v, time(0));
addConstant("__currentTime", v);
- mkString(v, thisSystem.c_str());
+ mkString(v, settings.thisSystem.c_str());
addConstant("__currentSystem", v);
// Miscellaneous
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 2118e4391..9c62e320f 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -74,7 +74,7 @@ void printMissing(StoreAPI & store, const PathSet & paths)
if (!unknown.empty()) {
printMsg(lvlInfo, format("don't know how to build these paths%1%:")
- % (readOnlyMode ? " (may be caused by read-only store access)" : ""));
+ % (settings.readOnlyMode ? " (may be caused by read-only store access)" : ""));
foreach (PathSet::iterator, i, unknown)
printMsg(lvlInfo, format(" %1%") % *i);
}
@@ -93,11 +93,20 @@ static void setLogType(string lt)
static bool showTrace = false;
+string getArg(const string & opt,
+ Strings::iterator & i, const Strings::iterator & end)
+{
+ ++i;
+ if (i == end) throw UsageError(format("`%1%' requires an argument") % opt);
+ return *i;
+}
+
/* Initialize and reorder arguments, then call the actual argument
processor. */
static void initAndRun(int argc, char * * argv)
{
- setDefaultsFromEnvironment();
+ settings.processEnvironment();
+ settings.loadConfFile();
/* Catch SIGINT. */
struct sigaction act;
@@ -156,20 +165,19 @@ static void initAndRun(int argc, char * * argv)
remaining.clear();
/* Process default options. */
- int verbosityDelta = 0;
+ int verbosityDelta = lvlInfo;
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
string arg = *i;
if (arg == "--verbose" || arg == "-v") verbosityDelta++;
else if (arg == "--quiet") verbosityDelta--;
else if (arg == "--log-type") {
- ++i;
- if (i == args.end()) throw UsageError("`--log-type' requires an argument");
- setLogType(*i);
+ string s = getArg(arg, i, args.end());
+ setLogType(s);
}
else if (arg == "--no-build-output" || arg == "-Q")
- buildVerbosity = lvlVomit;
+ settings.buildVerbosity = lvlVomit;
else if (arg == "--print-build-trace")
- printBuildTrace = true;
+ settings.printBuildTrace = true;
else if (arg == "--help") {
printHelp();
return;
@@ -179,23 +187,23 @@ static void initAndRun(int argc, char * * argv)
return;
}
else if (arg == "--keep-failed" || arg == "-K")
- keepFailed = true;
+ settings.keepFailed = true;
else if (arg == "--keep-going" || arg == "-k")
- keepGoing = true;
+ settings.keepGoing = true;
else if (arg == "--fallback")
- tryFallback = true;
+ settings.tryFallback = true;
else if (arg == "--max-jobs" || arg == "-j")
- maxBuildJobs = getIntArg<unsigned int>(arg, i, args.end());
+ settings.set("build-max-jobs", getArg(arg, i, args.end()));
else if (arg == "--cores")
- buildCores = getIntArg<unsigned int>(arg, i, args.end());
+ settings.set("build-cores", getArg(arg, i, args.end()));
else if (arg == "--readonly-mode")
- readOnlyMode = true;
+ settings.readOnlyMode = true;
else if (arg == "--max-silent-time")
- maxSilentTime = getIntArg<unsigned int>(arg, i, args.end());
+ settings.set("build-max-silent-time", getArg(arg, i, args.end()));
else if (arg == "--timeout")
- buildTimeout = getIntArg<unsigned int>(arg, i, args.end());
+ settings.set("build-timeout", getArg(arg, i, args.end()));
else if (arg == "--no-build-hook")
- useBuildHook = false;
+ settings.useBuildHook = false;
else if (arg == "--show-trace")
showTrace = true;
else if (arg == "--option") {
@@ -203,14 +211,15 @@ static void initAndRun(int argc, char * * argv)
string name = *i;
++i; if (i == args.end()) throw UsageError("`--option' requires two arguments");
string value = *i;
- overrideSetting(name, tokenizeString(value));
+ settings.set(name, value);
}
else remaining.push_back(arg);
}
- verbosityDelta += queryIntSetting("verbosity", lvlInfo);
verbosity = (Verbosity) (verbosityDelta < 0 ? 0 : verbosityDelta);
+ settings.update();
+
run(remaining);
/* Close the Nix database. */
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 4a2bc5218..0972d6e19 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -229,8 +229,6 @@ private:
public:
- bool cacheFailure;
-
/* Set if at least one derivation had a BuildError (i.e. permanent
failure). */
bool permanentFailure;
@@ -314,7 +312,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
if (result == ecNoSubstituters) ++nrNoSubstituters;
- if (waitees.empty() || (result == ecFailed && !keepGoing)) {
+ if (waitees.empty() || (result == ecFailed && !settings.keepGoing)) {
/* If we failed and keepGoing is not set, we remove all
remaining waitees. */
@@ -466,14 +464,13 @@ void UserLock::acquire()
{
assert(uid == 0);
- string buildUsersGroup = querySetting("build-users-group", "");
- assert(buildUsersGroup != "");
+ assert(settings.buildUsersGroup != "");
/* Get the members of the build-users-group. */
- struct group * gr = getgrnam(buildUsersGroup.c_str());
+ struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
if (!gr)
throw Error(format("the group `%1%' specified in `build-users-group' does not exist")
- % buildUsersGroup);
+ % settings.buildUsersGroup);
gid = gr->gr_gid;
/* Copy the result of getgrnam. */
@@ -485,7 +482,7 @@ void UserLock::acquire()
if (users.empty())
throw Error(format("the build users group `%1%' has no members")
- % buildUsersGroup);
+ % settings.buildUsersGroup);
/* Find a user account that isn't currently in use for another
build. */
@@ -495,11 +492,11 @@ void UserLock::acquire()
struct passwd * pw = getpwnam(i->c_str());
if (!pw)
throw Error(format("the user `%1%' in the group `%2%' does not exist")
- % *i % buildUsersGroup);
+ % *i % settings.buildUsersGroup);
- createDirs(nixStateDir + "/userpool");
+ createDirs(settings.nixStateDir + "/userpool");
- fnUserLock = (format("%1%/userpool/%2%") % nixStateDir % pw->pw_uid).str();
+ fnUserLock = (format("%1%/userpool/%2%") % settings.nixStateDir % pw->pw_uid).str();
if (lockedPaths.find(fnUserLock) != lockedPaths.end())
/* We already have a lock on this one. */
@@ -519,7 +516,7 @@ void UserLock::acquire()
/* Sanity check... */
if (uid == getuid() || uid == geteuid())
throw Error(format("the Nix user should not be a member of `%1%'")
- % buildUsersGroup);
+ % settings.buildUsersGroup);
return;
}
@@ -527,7 +524,7 @@ void UserLock::acquire()
throw Error(format("all build users are currently in use; "
"consider creating additional users and adding them to the `%1%' group")
- % buildUsersGroup);
+ % settings.buildUsersGroup);
}
@@ -546,7 +543,7 @@ static void runSetuidHelper(const string & command,
const string & arg)
{
Path program = getEnv("NIX_SETUID_HELPER",
- nixLibexecDir + "/nix-setuid-helper");
+ settings.nixLibexecDir + "/nix-setuid-helper");
/* Fork. */
Pid pid;
@@ -601,12 +598,6 @@ bool amPrivileged()
}
-bool haveBuildUsers()
-{
- return querySetting("build-users-group", "") != "";
-}
-
-
void getOwnership(const Path & path)
{
runSetuidHelper("get-ownership", path);
@@ -622,7 +613,7 @@ void deletePathWrapped(const Path & path,
} catch (SysError & e) {
/* If this failed due to a permission error, then try it with
the setuid helper. */
- if (haveBuildUsers() && !amPrivileged()) {
+ if (settings.buildUsersGroup != "" && !amPrivileged()) {
getOwnership(path);
deletePath(path, bytesFreed, blocksFreed);
} else
@@ -701,9 +692,9 @@ HookInstance::HookInstance()
throw SysError("dupping builder's stdout/stderr");
/* XXX: Pass `buildTimeout' to the hook? */
- execl(buildHook.c_str(), buildHook.c_str(), thisSystem.c_str(),
- (format("%1%") % maxSilentTime).str().c_str(),
- (format("%1%") % printBuildTrace).str().c_str(),
+ execl(buildHook.c_str(), buildHook.c_str(), settings.thisSystem.c_str(),
+ (format("%1%") % settings.maxSilentTime).str().c_str(),
+ (format("%1%") % settings.printBuildTrace).str().c_str(),
NULL);
throw SysError(format("executing `%1%'") % buildHook);
@@ -943,7 +934,7 @@ void DerivationGoal::init()
{
trace("init");
- if (readOnlyMode)
+ if (settings.readOnlyMode)
throw Error(format("cannot build derivation `%1%' - no write access to the Nix store") % drvPath);
/* The first thing to do is to make sure that the derivation
@@ -995,7 +986,7 @@ void DerivationGoal::haveDerivation()
/* We are first going to try to create the invalid output paths
through substitutes. If that doesn't work, we'll build
them. */
- if (queryBoolSetting("build-use-substitutes", true))
+ if (settings.useSubstitutes)
foreach (PathSet::iterator, i, invalidOutputs)
addWaitee(worker.makeSubstitutionGoal(*i));
@@ -1010,7 +1001,7 @@ void DerivationGoal::outputsSubstituted()
{
trace("all outputs substituted (maybe)");
- if (nrFailed > 0 && nrFailed > nrNoSubstituters && !tryFallback)
+ if (nrFailed > 0 && nrFailed > nrNoSubstituters && !settings.tryFallback)
throw Error(format("some substitutes for the outputs of derivation `%1%' failed; try `--fallback'") % drvPath);
nrFailed = nrNoSubstituters = 0;
@@ -1109,9 +1100,9 @@ PathSet outputPaths(const DerivationOutputs & outputs)
static bool canBuildLocally(const string & platform)
{
- return platform == thisSystem
+ return platform == settings.thisSystem
#ifdef CAN_DO_LINUX32_BUILDS
- || (platform == "i686-linux" && thisSystem == "x86_64-linux")
+ || (platform == "i686-linux" && settings.thisSystem == "x86_64-linux")
#endif
;
}
@@ -1213,7 +1204,7 @@ void DerivationGoal::tryToBuild()
derivation prefers to be done locally, do it even if
maxBuildJobs is 0. */
unsigned int curBuilds = worker.getNrLocalBuilds();
- if (curBuilds >= maxBuildJobs && !(preferLocalBuild && curBuilds == 0)) {
+ if (curBuilds >= settings.maxBuildJobs && !(preferLocalBuild && curBuilds == 0)) {
worker.waitForBuildSlot(shared_from_this());
outputLocks.unlock();
return;
@@ -1228,7 +1219,7 @@ void DerivationGoal::tryToBuild()
printMsg(lvlError, e.msg());
outputLocks.unlock();
buildUser.release();
- if (printBuildTrace)
+ if (settings.printBuildTrace)
printMsg(lvlError, format("@ build-failed %1% %2% %3% %4%")
% drvPath % drv.outputs["out"].path % 0 % e.msg());
worker.permanentFailure = true;
@@ -1360,7 +1351,7 @@ void DerivationGoal::buildDone()
bool hookError = hook &&
(!WIFEXITED(status) || WEXITSTATUS(status) != 100);
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
if (hook && hookError)
printMsg(lvlError, format("@ hook-failed %1% %2% %3% %4%")
% drvPath % drv.outputs["out"].path % status % e.msg());
@@ -1376,7 +1367,7 @@ void DerivationGoal::buildDone()
able to access the network). Hook errors (like
communication problems with the remote machine) shouldn't
be cached either. */
- if (worker.cacheFailure && !hookError && !fixedOutput)
+ if (settings.cacheFailure && !hookError && !fixedOutput)
foreach (DerivationOutputs::iterator, i, drv.outputs)
worker.store.registerFailedPath(i->second.path);
@@ -1388,7 +1379,7 @@ void DerivationGoal::buildDone()
/* Release the build user, if applicable. */
buildUser.release();
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
printMsg(lvlError, format("@ build-succeeded %1% %2%")
% drvPath % drv.outputs["out"].path);
}
@@ -1399,7 +1390,7 @@ void DerivationGoal::buildDone()
HookReply DerivationGoal::tryBuildHook()
{
- if (!useBuildHook || getEnv("NIX_BUILD_HOOK") == "") return rpDecline;
+ if (!settings.useBuildHook || getEnv("NIX_BUILD_HOOK") == "") return rpDecline;
if (!worker.hook)
worker.hook = boost::shared_ptr<HookInstance>(new HookInstance);
@@ -1412,7 +1403,7 @@ HookReply DerivationGoal::tryBuildHook()
/* Send the request to the hook. */
writeLine(worker.hook->toHook.writeSide, (format("%1% %2% %3% %4%")
- % (worker.getNrLocalBuilds() < maxBuildJobs ? "1" : "0")
+ % (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0")
% drv.platform % drvPath % concatStringsSep(",", features)).str());
/* Read the first line of input, which should be a word indicating
@@ -1471,7 +1462,7 @@ HookReply DerivationGoal::tryBuildHook()
fds.insert(hook->builderOut.readSide);
worker.childStarted(shared_from_this(), hook->pid, fds, false, false);
- if (printBuildTrace)
+ if (settings.printBuildTrace)
printMsg(lvlError, format("@ build-started %1% %2% %3% %4%")
% drvPath % drv.outputs["out"].path % drv.platform % logFile);
@@ -1502,7 +1493,7 @@ void DerivationGoal::startBuilder()
if (!canBuildLocally(drv.platform))
throw Error(
format("a `%1%' is required to build `%3%', but I am a `%2%'")
- % drv.platform % thisSystem % drvPath);
+ % drv.platform % settings.thisSystem % drvPath);
/* Construct the environment passed to the builder. */
@@ -1523,10 +1514,10 @@ void DerivationGoal::startBuilder()
shouldn't care, but this is useful for purity checking (e.g.,
the compiler or linker might only want to accept paths to files
in the store or in the build directory). */
- env["NIX_STORE"] = nixStore;
+ env["NIX_STORE"] = settings.nixStore;
/* The maximum number of cores to utilize for parallel building. */
- env["NIX_BUILD_CORES"] = (format("%d") % buildCores).str();
+ env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
/* Add all bindings specified in the derivation. */
foreach (StringPairs::iterator, i, drv.env)
@@ -1618,7 +1609,7 @@ void DerivationGoal::startBuilder()
/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
- if (haveBuildUsers()) {
+ if (settings.buildUsersGroup != "") {
buildUser.acquire();
assert(buildUser.getUID() != 0);
assert(buildUser.getGID() != 0);
@@ -1640,15 +1631,15 @@ void DerivationGoal::startBuilder()
the builder can create its output but not mess with the
outputs of other processes). */
struct stat st;
- if (stat(nixStore.c_str(), &st) == -1)
- throw SysError(format("cannot stat `%1%'") % nixStore);
+ if (stat(settings.nixStore.c_str(), &st) == -1)
+ throw SysError(format("cannot stat `%1%'") % settings.nixStore);
if (!(st.st_mode & S_ISVTX) ||
((st.st_mode & S_IRWXG) != S_IRWXG) ||
(st.st_gid != buildUser.getGID()))
throw Error(format(
"builder does not have write permission to `%2%'; "
"try `chgrp %1% %2%; chmod 1775 %2%'")
- % buildUser.getGID() % nixStore);
+ % buildUser.getGID() % settings.nixStore);
}
@@ -1657,7 +1648,7 @@ void DerivationGoal::startBuilder()
functions like fetchurl (which needs a proper /etc/resolv.conf)
work properly. Purity checking for fixed-output derivations
is somewhat pointless anyway. */
- useChroot = queryBoolSetting("build-use-chroot", false);
+ useChroot = settings.useChroot;
if (fixedOutput) useChroot = false;
@@ -1707,16 +1698,8 @@ void DerivationGoal::startBuilder()
writeFile(chrootRootDir + "/etc/hosts", "127.0.0.1 localhost\n");
/* Bind-mount a user-configurable set of directories from the
- host file system. The `/dev/pts' directory must be mounted
- separately so that newly-created pseudo-terminals show
- up. */
- Paths defaultDirs;
- defaultDirs.push_back("/dev");
- defaultDirs.push_back("/dev/pts");
-
- Paths dirsInChroot_ = querySetting("build-chroot-dirs", defaultDirs);
- dirsInChroot.insert(dirsInChroot_.begin(), dirsInChroot_.end());
-
+ host file system. */
+ dirsInChroot = settings.dirsInChroot;
dirsInChroot.insert(tmpDir);
/* Make the closure of the inputs available in the chroot,
@@ -1726,8 +1709,8 @@ void DerivationGoal::startBuilder()
can be bind-mounted). !!! As an extra security
precaution, make the fake Nix store only writable by the
build user. */
- createDirs(chrootRootDir + nixStore);
- chmod(chrootRootDir + nixStore, 01777);
+ createDirs(chrootRootDir + settings.nixStore);
+ chmod(chrootRootDir + settings.nixStore, 01777);
foreach (PathSet::iterator, i, inputPaths) {
struct stat st;
@@ -1827,7 +1810,7 @@ void DerivationGoal::startBuilder()
worker.childStarted(shared_from_this(), pid,
singleton<set<int> >(builderOut.readSide), true, true);
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
printMsg(lvlError, format("@ build-started %1% %2% %3% %4%")
% drvPath % drv.outputs["out"].path % drv.platform % logFile);
}
@@ -1907,16 +1890,14 @@ void DerivationGoal::initChild()
#ifdef CAN_DO_LINUX32_BUILDS
/* Change the personality to 32-bit if we're doing an
i686-linux build on an x86_64-linux machine. */
- if (drv.platform == "i686-linux" && thisSystem == "x86_64-linux") {
+ if (drv.platform == "i686-linux" && settings.thisSystem == "x86_64-linux") {
if (personality(0x0008 | 0x8000000 /* == PER_LINUX32_3GB */) == -1)
throw SysError("cannot set i686-linux personality");
}
/* Impersonate a Linux 2.6 machine to get some determinism in
builds that depend on the kernel version. */
- if ((drv.platform == "i686-linux" || drv.platform == "x86_64-linux") &&
- queryBoolSetting("build-impersonate-linux-26", true))
- {
+ if ((drv.platform == "i686-linux" || drv.platform == "x86_64-linux") && settings.impersonateLinux26) {
int cur = personality(0xffffffff);
if (cur != -1) personality(cur | 0x0020000 /* == UNAME26 */);
}
@@ -1958,7 +1939,7 @@ void DerivationGoal::initChild()
} else {
/* Let the setuid helper take care of it. */
- program = nixLibexecDir + "/nix-setuid-helper";
+ program = settings.nixLibexecDir + "/nix-setuid-helper";
args.push_back(program.c_str());
args.push_back("run-builder");
user = buildUser.getUser().c_str();
@@ -2126,13 +2107,13 @@ string drvsLogDir = "drvs";
Path DerivationGoal::openLogFile()
{
- if (!queryBoolSetting("build-keep-log", true)) return "";
+ if (!settings.keepLog) return "";
/* Create a log file. */
- Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
+ Path dir = (format("%1%/%2%") % settings.nixLogDir % drvsLogDir).str();
createDirs(dir);
- if (queryBoolSetting("build-compress-log", true)) {
+ if (settings.compressLog) {
Path logFileName = (format("%1%/%2%.bz2") % dir % baseNameOf(drvPath)).str();
AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
@@ -2179,7 +2160,7 @@ void DerivationGoal::closeLogFile()
void DerivationGoal::deleteTmpDir(bool force)
{
if (tmpDir != "") {
- if (keepFailed && !force) {
+ if (settings.keepFailed && !force) {
printMsg(lvlError,
format("builder for `%1%' failed; keeping build directory `%2%'")
% drvPath % tmpDir);
@@ -2199,7 +2180,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
if ((hook && fd == hook->builderOut.readSide) ||
(!hook && fd == builderOut.readSide))
{
- if (verbosity >= buildVerbosity)
+ if (verbosity >= settings.buildVerbosity)
writeToStderr((unsigned char *) data.data(), data.size());
if (bzLogFile) {
int err;
@@ -2235,13 +2216,13 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid)
bool DerivationGoal::pathFailed(const Path & path)
{
- if (!worker.cacheFailure) return false;
+ if (!settings.cacheFailure) return false;
if (!worker.store.hasPathFailed(path)) return false;
printMsg(lvlError, format("builder for `%1%' failed previously (cached)") % path);
- if (printBuildTrace)
+ if (settings.printBuildTrace)
printMsg(lvlError, format("@ build-failed %1% %2% cached") % drvPath % path);
worker.permanentFailure = true;
@@ -2362,10 +2343,10 @@ void SubstitutionGoal::init()
return;
}
- if (readOnlyMode)
+ if (settings.readOnlyMode)
throw Error(format("cannot substitute path `%1%' - no write access to the Nix store") % storePath);
- subs = substituters;
+ subs = settings.substituters;
tryNext();
}
@@ -2437,7 +2418,7 @@ void SubstitutionGoal::tryToRun()
is maxBuildJobs == 0 (no local builds allowed), we still allow
a substituter to run. This is because substitutions cannot be
distributed to another machine via the build hook. */
- if (worker.getNrLocalBuilds() >= (maxBuildJobs == 0 ? 1 : maxBuildJobs)) {
+ if (worker.getNrLocalBuilds() >= (settings.maxBuildJobs == 0 ? 1 : settings.maxBuildJobs)) {
worker.waitForBuildSlot(shared_from_this());
return;
}
@@ -2496,7 +2477,7 @@ void SubstitutionGoal::tryToRun()
/* Pass configuration options (including those overriden
with --option) to the substituter. */
- setenv("_NIX_OPTIONS", packSettings().c_str(), 1);
+ setenv("_NIX_OPTIONS", settings.pack().c_str(), 1);
/* Fill in the arguments. */
Strings args;
@@ -2525,7 +2506,7 @@ void SubstitutionGoal::tryToRun()
state = &SubstitutionGoal::finished;
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
printMsg(lvlError, format("@ substituter-started %1% %2%")
% storePath % sub);
}
@@ -2583,7 +2564,7 @@ void SubstitutionGoal::finished()
printMsg(lvlInfo, e.msg());
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
printMsg(lvlError, format("@ substituter-failed %1% %2% %3%")
% storePath % status % e.msg());
}
@@ -2611,7 +2592,7 @@ void SubstitutionGoal::finished()
printMsg(lvlChatty,
format("substitution of path `%1%' succeeded") % storePath);
- if (printBuildTrace) {
+ if (settings.printBuildTrace) {
printMsg(lvlError, format("@ substituter-succeeded %1%") % storePath);
}
@@ -2622,7 +2603,7 @@ void SubstitutionGoal::finished()
void SubstitutionGoal::handleChildOutput(int fd, const string & data)
{
assert(fd == logPipe.readSide);
- if (verbosity >= buildVerbosity)
+ if (verbosity >= settings.buildVerbosity)
writeToStderr((unsigned char *) data.data(), data.size());
/* Don't write substitution output to a log file for now. We
probably should, though. */
@@ -2650,7 +2631,6 @@ Worker::Worker(LocalStore & store)
working = true;
nrLocalBuilds = 0;
lastWokenUp = 0;
- cacheFailure = queryBoolSetting("build-cache-failure", false);
permanentFailure = false;
}
@@ -2715,7 +2695,7 @@ void Worker::removeGoal(GoalPtr goal)
topGoals.erase(goal);
/* If a top-level goal failed, then kill all other goals
(unless keepGoing was set). */
- if (goal->getExitCode() == Goal::ecFailed && !keepGoing)
+ if (goal->getExitCode() == Goal::ecFailed && !settings.keepGoing)
topGoals.clear();
}
@@ -2787,7 +2767,7 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
void Worker::waitForBuildSlot(GoalPtr goal)
{
debug("wait for build slot");
- if (getNrLocalBuilds() < maxBuildJobs)
+ if (getNrLocalBuilds() < settings.maxBuildJobs)
wakeUp(goal); /* we can do it right away */
else
wantingToBuild.insert(goal);
@@ -2836,7 +2816,7 @@ void Worker::run(const Goals & _topGoals)
if (!children.empty() || !waitingForAWhile.empty())
waitForInput();
else {
- if (awake.empty() && maxBuildJobs == 0) throw Error(
+ if (awake.empty() && settings.maxBuildJobs == 0) throw Error(
"unable to start any build; either increase `--max-jobs' "
"or enable distributed builds");
assert(!awake.empty());
@@ -2846,9 +2826,9 @@ void Worker::run(const Goals & _topGoals)
/* If --keep-going is not set, it's possible that the main goal
exited while some of its subgoals were still active. But if
--keep-going *is* set, then they must all be finished now. */
- assert(!keepGoing || awake.empty());
- assert(!keepGoing || wantingToBuild.empty());
- assert(!keepGoing || children.empty());
+ assert(!settings.keepGoing || awake.empty());
+ assert(!settings.keepGoing || wantingToBuild.empty());
+ assert(!settings.keepGoing || children.empty());
}
@@ -2868,15 +2848,15 @@ void Worker::waitForInput()
time_t before = time(0);
/* If a global timeout has been set, sleep until it's done. */
- if (buildTimeout != 0) {
+ if (settings.buildTimeout != 0) {
useTimeout = true;
if (lastWait == 0 || lastWait > before) lastWait = before;
- timeout.tv_sec = std::max((time_t) 0, lastWait + buildTimeout - before);
+ timeout.tv_sec = std::max((time_t) 0, lastWait + settings.buildTimeout - before);
}
/* If we're monitoring for silence on stdout/stderr, sleep until
the first deadline for any child. */
- if (maxSilentTime != 0) {
+ if (settings.maxSilentTime != 0) {
time_t oldest = 0;
foreach (Children::iterator, i, children) {
if (i->second.monitorForSilence) {
@@ -2885,7 +2865,7 @@ void Worker::waitForInput()
}
}
if (oldest) {
- time_t silenceTimeout = std::max((time_t) 0, oldest + maxSilentTime - before);
+ time_t silenceTimeout = std::max((time_t) 0, oldest + settings.maxSilentTime - before);
timeout.tv_sec = useTimeout
? std::min(silenceTimeout, timeout.tv_sec)
: silenceTimeout;
@@ -2896,14 +2876,12 @@ void Worker::waitForInput()
/* If we are polling goals that are waiting for a lock, then wake
up after a few seconds at most. */
- int wakeUpInterval = queryIntSetting("build-poll-interval", 5);
-
if (!waitingForAWhile.empty()) {
useTimeout = true;
if (lastWokenUp == 0)
printMsg(lvlError, "waiting for locks or build slots...");
if (lastWokenUp == 0 || lastWokenUp > before) lastWokenUp = before;
- timeout.tv_sec = std::max((time_t) 0, lastWokenUp + wakeUpInterval - before);
+ timeout.tv_sec = std::max((time_t) 0, lastWokenUp + settings.pollInterval - before);
} else lastWokenUp = 0;
using namespace std;
@@ -2969,27 +2947,27 @@ void Worker::waitForInput()
}
}
- if (maxSilentTime != 0 &&
+ if (settings.maxSilentTime != 0 &&
j->second.monitorForSilence &&
- after - j->second.lastOutput >= (time_t) maxSilentTime)
+ after - j->second.lastOutput >= (time_t) settings.maxSilentTime)
{
printMsg(lvlError,
format("%1% timed out after %2% seconds of silence")
- % goal->getName() % maxSilentTime);
+ % goal->getName() % settings.maxSilentTime);
goal->cancel();
}
- if (buildTimeout != 0 &&
- after - before >= (time_t) buildTimeout)
+ if (settings.buildTimeout != 0 &&
+ after - before >= (time_t) settings.buildTimeout)
{
printMsg(lvlError,
format("%1% timed out after %2% seconds of activity")
- % goal->getName() % buildTimeout);
+ % goal->getName() % settings.buildTimeout);
goal->cancel();
}
}
- if (!waitingForAWhile.empty() && lastWokenUp + wakeUpInterval <= after) {
+ if (!waitingForAWhile.empty() && lastWokenUp + settings.pollInterval <= after) {
lastWokenUp = after;
foreach (WeakGoals::iterator, i, waitingForAWhile) {
GoalPtr goal = i->lock();
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 97343d57d..73047c753 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -12,7 +12,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
{
recursive = false;
string algo = hashAlgo;
-
+
if (string(algo, 0, 2) == "r:") {
recursive = true;
algo = string(algo, 2);
@@ -21,7 +21,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
hashType = parseHashType(algo);
if (hashType == htUnknown)
throw Error(format("unknown hash algorithm `%1%'") % algo);
-
+
hash = parseHash(hashType, this->hash);
}
@@ -38,7 +38,7 @@ Path writeDerivation(StoreAPI & store,
held during a garbage collection). */
string suffix = name + drvExtension;
string contents = unparseDerivation(drv);
- return readOnlyMode
+ return settings.readOnlyMode
? computeStorePathForText(suffix, contents, references)
: store.addTextToStore(suffix, contents, references);
}
@@ -51,7 +51,7 @@ static Path parsePath(std::istream & str)
throw Error(format("bad path `%1%' in derivation") % s);
return s;
}
-
+
static StringSet parseStrings(std::istream & str, bool arePaths)
{
@@ -60,7 +60,7 @@ static StringSet parseStrings(std::istream & str, bool arePaths)
res.insert(arePaths ? parsePath(str) : parseString(str));
return res;
}
-
+
Derivation parseDerivation(const string & s)
{
@@ -106,7 +106,7 @@ Derivation parseDerivation(const string & s)
expect(str, ")");
drv.env[name] = value;
}
-
+
expect(str, ")");
return drv;
}
@@ -165,7 +165,7 @@ string unparseDerivation(const Derivation & drv)
s += "],";
printStrings(s, drv.inputSrcs.begin(), drv.inputSrcs.end());
-
+
s += ','; printString(s, drv.platform);
s += ','; printString(s, drv.builder);
s += ','; printStrings(s, drv.args.begin(), drv.args.end());
@@ -178,9 +178,9 @@ string unparseDerivation(const Derivation & drv)
s += ','; printString(s, i->second);
s += ')';
}
-
+
s += "])";
-
+
return s;
}
@@ -190,7 +190,7 @@ bool isDerivation(const string & fileName)
return hasSuffix(fileName, drvExtension);
}
-
+
bool isFixedOutputDrv(const Derivation & drv)
{
return drv.outputs.size() == 1 &&
@@ -247,7 +247,7 @@ Hash hashDerivationModulo(StoreAPI & store, Derivation drv)
inputs2[printHash(h)] = i->second;
}
drv.inputDrvs = inputs2;
-
+
return hashString(htSHA256, unparseDerivation(drv));
}
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 874efe4d3..1355702f8 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -34,10 +34,10 @@ static const int defaultGcLevel = 1000;
int LocalStore::openGCLock(LockType lockType)
{
Path fnGCLock = (format("%1%/%2%")
- % nixStateDir % gcLockName).str();
-
+ % settings.nixStateDir % gcLockName).str();
+
debug(format("acquiring global GC lock `%1%'") % fnGCLock);
-
+
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT, 0600);
if (fdGCLock == -1)
throw SysError(format("opening global GC lock `%1%'") % fnGCLock);
@@ -51,7 +51,7 @@ int LocalStore::openGCLock(LockType lockType)
/* !!! Restrict read permission on the GC root. Otherwise any
process that can open the file for reading can DoS the
collector. */
-
+
return fdGCLock.borrow();
}
@@ -85,7 +85,7 @@ void LocalStore::addIndirectRoot(const Path & path)
{
string hash = printHash32(hashString(htSHA1, path));
Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
- % nixStateDir % gcRootsDir % hash).str());
+ % settings.nixStateDir % gcRootsDir % hash).str());
createSymlink(realRoot, path);
}
@@ -113,15 +113,15 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
else {
if (!allowOutsideRootsDir) {
- Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
-
+ Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str());
+
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
throw Error(format(
"path `%1%' is not a valid garbage collector root; "
"it's not in the directory `%2%'")
% gcRoot % rootsDir);
}
-
+
createSymlink(gcRoot, storePath);
}
@@ -130,10 +130,10 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
Instead of reading all the roots, it would be more efficient to
check if the root is in a directory in or linked from the
gcroots directory. */
- if (queryBoolSetting("gc-check-reachability", false)) {
+ if (settings.checkRootReachability) {
Roots roots = store.findRoots();
if (roots.find(gcRoot) == roots.end())
- printMsg(lvlError,
+ printMsg(lvlError,
format(
"warning: `%1%' is not in a directory where the garbage collector looks for roots; "
"therefore, `%2%' might be removed by the garbage collector")
@@ -144,7 +144,7 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
progress. This prevents the set of permanent roots from
increasing while a GC is in progress. */
store.syncWithGC();
-
+
return gcRoot;
}
@@ -160,23 +160,23 @@ void LocalStore::addTempRoot(const Path & path)
if (fdTempRoots == -1) {
while (1) {
- Path dir = (format("%1%/%2%") % nixStateDir % tempRootsDir).str();
+ Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str();
createDirs(dir);
-
+
fnTempRoots = (format("%1%/%2%")
% dir % getpid()).str();
AutoCloseFD fdGCLock = openGCLock(ltRead);
-
+
if (pathExists(fnTempRoots))
/* It *must* be stale, since there can be no two
processes with the same pid. */
unlink(fnTempRoots.c_str());
- fdTempRoots = openLockFile(fnTempRoots, true);
+ fdTempRoots = openLockFile(fnTempRoots, true);
fdGCLock.close();
-
+
debug(format("acquiring read lock on `%1%'") % fnTempRoots);
lockFile(fdTempRoots, ltRead, true);
@@ -186,7 +186,7 @@ void LocalStore::addTempRoot(const Path & path)
if (fstat(fdTempRoots, &st) == -1)
throw SysError(format("statting `%1%'") % fnTempRoots);
if (st.st_size == 0) break;
-
+
/* The garbage collector deleted this file before we could
get a lock. (It won't delete the file after we get a
lock.) Try again. */
@@ -218,7 +218,7 @@ void removeTempRoots()
/* Automatically clean up the temporary roots file when we exit. */
-struct RemoveTempRoots
+struct RemoveTempRoots
{
~RemoveTempRoots()
{
@@ -238,10 +238,10 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
/* Read the `temproots' directory for per-process temporary root
files. */
Strings tempRootFiles = readDirectory(
- (format("%1%/%2%") % nixStateDir % tempRootsDir).str());
+ (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str());
foreach (Strings::iterator, i, tempRootFiles) {
- Path path = (format("%1%/%2%/%3%") % nixStateDir % tempRootsDir % *i).str();
+ Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % *i).str();
debug(format("reading temporary root file `%1%'") % path);
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
@@ -295,7 +295,7 @@ static void findRoots(StoreAPI & store, const Path & path,
bool recurseSymlinks, bool deleteStale, Roots & roots)
{
try {
-
+
struct stat st;
if (lstat(path.c_str(), &st) == -1)
throw SysError(format("statting `%1%'") % path);
@@ -315,7 +315,7 @@ static void findRoots(StoreAPI & store, const Path & path,
debug(format("found root `%1%' in `%2%'")
% target % path);
Path storePath = toStorePath(target);
- if (store.isValidPath(storePath))
+ if (store.isValidPath(storePath))
roots[path] = storePath;
else
printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'")
@@ -350,7 +350,7 @@ static void findRoots(StoreAPI & store, const Path & path,
static Roots findRoots(StoreAPI & store, bool deleteStale)
{
Roots roots;
- Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
+ Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str());
findRoots(store, rootsDir, true, deleteStale, roots);
return roots;
}
@@ -365,16 +365,16 @@ Roots LocalStore::findRoots()
static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
{
Path rootFinder = getEnv("NIX_ROOT_FINDER",
- nixLibexecDir + "/nix/find-runtime-roots.pl");
+ settings.nixLibexecDir + "/nix/find-runtime-roots.pl");
if (rootFinder.empty()) return;
-
+
debug(format("executing `%1%' to find additional roots") % rootFinder);
string result = runProgram(rootFinder);
Strings paths = tokenizeString(result, "\n");
-
+
foreach (Strings::iterator, i, paths) {
if (isInStore(*i)) {
Path path = toStorePath(*i);
@@ -557,7 +557,7 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path)
} else
printMsg(lvlTalkative, format("would delete `%1%'") % path);
-
+
state.deleted.insert(path);
if (state.options.action != GCOptions::gcReturnLive)
state.results.paths.insert(path);
@@ -605,10 +605,10 @@ void LocalStore::removeUnusedLinks()
void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
{
GCState state(results);
- state.options = options;
-
- state.gcKeepOutputs = queryBoolSetting("gc-keep-outputs", false);
- state.gcKeepDerivations = queryBoolSetting("gc-keep-derivations", true);
+ state.options = options;
+
+ state.gcKeepOutputs = settings.gcKeepOutputs;
+ state.gcKeepDerivations = settings.gcKeepDerivations;
/* Using `--ignore-liveness' with `--delete' can have unintended
consequences if `gc-keep-outputs' or `gc-keep-derivations' are
@@ -618,7 +618,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
state.gcKeepOutputs = false;
state.gcKeepDerivations = false;
}
-
+
/* Acquire the global GC root. This prevents
a) New roots from being added.
b) Processes from creating new temporary root files. */
@@ -659,18 +659,18 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
if (!tryToDelete(state, *i))
throw Error(format("cannot delete path `%1%' since it is still alive") % *i);
}
-
+
} else {
-
+
if (shouldDelete(state.options.action))
printMsg(lvlError, format("deleting garbage..."));
else
printMsg(lvlError, format("determining live/dead paths..."));
-
+
try {
- AutoCloseDir dir = opendir(nixStore.c_str());
- if (!dir) throw SysError(format("opening directory `%1%'") % nixStore);
+ AutoCloseDir dir = opendir(settings.nixStore.c_str());
+ if (!dir) throw SysError(format("opening directory `%1%'") % settings.nixStore);
/* Read the store and immediately delete all paths that
aren't valid. When using --max-freed etc., deleting
@@ -684,14 +684,14 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
checkInterrupt();
string name = dirent->d_name;
if (name == "." || name == "..") continue;
- Path path = nixStore + "/" + name;
+ Path path = settings.nixStore + "/" + name;
if (isValidPath(path))
entries.push_back(path);
else
tryToDelete(state, path);
}
- dir.close();
+ dir.close();
/* Now delete the unreachable valid paths. Randomise the
order in which we delete entries to make the collector
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index a28e08427..7dc2e714b 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -10,38 +10,63 @@
namespace nix {
-string nixStore = "/UNINIT";
-string nixDataDir = "/UNINIT";
-string nixLogDir = "/UNINIT";
-string nixStateDir = "/UNINIT";
-string nixDBPath = "/UNINIT";
-string nixConfDir = "/UNINIT";
-string nixLibexecDir = "/UNINIT";
-string nixBinDir = "/UNINIT";
+Settings settings;
-bool keepFailed = false;
-bool keepGoing = false;
-bool tryFallback = false;
-Verbosity buildVerbosity = lvlError;
-unsigned int maxBuildJobs = 1;
-unsigned int buildCores = 1;
-bool readOnlyMode = false;
-string thisSystem = "unset";
-time_t maxSilentTime = 0;
-time_t buildTimeout = 0;
-Paths substituters;
-bool useBuildHook = true;
-bool printBuildTrace = false;
+Settings::Settings()
+{
+ keepFailed = false;
+ keepGoing = false;
+ tryFallback = false;
+ buildVerbosity = lvlError;
+ maxBuildJobs = 1;
+ buildCores = 1;
+ readOnlyMode = false;
+ thisSystem = SYSTEM;
+ maxSilentTime = 0;
+ buildTimeout = 0;
+ useBuildHook = true;
+ printBuildTrace = false;
+ reservedSize = 1024 * 1024;
+ fsyncMetadata = true;
+ useSQLiteWAL = true;
+ syncBeforeRegistering = false;
+ useSubstitutes = true;
+ useChroot = false;
+ dirsInChroot.insert("/dev");
+ dirsInChroot.insert("/dev/pts");
+ impersonateLinux26 = false;
+ keepLog = true;
+ compressLog = true;
+ cacheFailure = false;
+ pollInterval = 5;
+ checkRootReachability = false;
+ gcKeepOutputs = false;
+ gcKeepDerivations = true;
+ autoOptimiseStore = true;
+ envKeepDerivations = false;
+}
-static bool settingsRead = false;
-
-typedef std::map<string, Strings> Settings;
-static Settings settings;
+void Settings::processEnvironment()
+{
+ nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)));
+ nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
+ 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));
+ nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR));
+ nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR));
-/* Overriden settings. */
-Settings settingsCmdline;
+ string subs = getEnv("NIX_SUBSTITUTERS", "default");
+ if (subs == "default") {
+ substituters.push_back(nixLibexecDir + "/nix/substituters/copy-from-other-stores.pl");
+ substituters.push_back(nixLibexecDir + "/nix/substituters/download-using-manifests.pl");
+ substituters.push_back(nixLibexecDir + "/nix/substituters/download-from-binary-cache.pl");
+ } else
+ substituters = tokenizeString(subs, ":");
+}
string & at(Strings & ss, unsigned int n)
@@ -52,7 +77,7 @@ string & at(Strings & ss, unsigned int n)
}
-static void readSettings()
+void Settings::loadConfFile()
{
Path settingsFile = (format("%1%/%2%") % nixConfDir % "nix.conf").str();
if (!pathExists(settingsFile)) return;
@@ -80,104 +105,88 @@ static void readSettings()
Strings::iterator i = tokens.begin();
advance(i, 2);
- settings[name] = Strings(i, tokens.end());
+ settings[name] = concatStringsSep(" ", Strings(i, tokens.end())); // FIXME: slow
};
-
- settings.insert(settingsCmdline.begin(), settingsCmdline.end());
-
- settingsRead = true;
}
-Strings querySetting(const string & name, const Strings & def)
+void Settings::set(const string & name, const string & value)
{
- if (!settingsRead) readSettings();
- Settings::iterator i = settings.find(name);
- return i == settings.end() ? def : i->second;
+ settings[name] = value;
}
-string querySetting(const string & name, const string & def)
+void Settings::update()
{
- Strings defs;
- defs.push_back(def);
-
- Strings value = querySetting(name, defs);
- if (value.size() != 1)
- throw Error(format("configuration option `%1%' should not be a list") % name);
-
- return value.front();
+ get(thisSystem, "system");
+ get(maxBuildJobs, "build-max-jobs");
+ get(buildCores, "build-cores");
+ get(maxSilentTime, "build-max-silent-time");
+ get(buildTimeout, "build-timeout");
+ get(reservedSize, "gc-reserved-space");
+ get(fsyncMetadata, "fsync-metadata");
+ get(useSQLiteWAL, "use-sqlite-wal");
+ get(syncBeforeRegistering, "sync-before-registering");
+ get(useSubstitutes, "build-use-substitutes");
+ get(buildUsersGroup, "build-users-group");
+ get(useChroot, "build-use-chroot");
+ get(dirsInChroot, "build-chroot-dirs");
+ get(impersonateLinux26, "build-impersonate-linux-26");
+ get(keepLog, "build-keep-log");
+ get(compressLog, "build-compress-log");
+ get(cacheFailure, "build-cache-failure");
+ get(pollInterval, "build-poll-interval");
+ get(checkRootReachability, "gc-check-reachability");
+ get(gcKeepOutputs, "gc-keep-outputs");
+ get(gcKeepDerivations, "gc-keep-derivations");
+ get(autoOptimiseStore, "auto-optimise-store");
+ get(envKeepDerivations, "env-keep-derivations");
}
-bool queryBoolSetting(const string & name, bool def)
+void Settings::get(string & res, const string & name)
{
- string v = querySetting(name, def ? "true" : "false");
- if (v == "true") return true;
- else if (v == "false") return false;
- else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
- % name % v);
+ SettingsMap::iterator i = settings.find(name);
+ if (i == settings.end()) return;
+ res = i->second;
}
-unsigned int queryIntSetting(const string & name, unsigned int def)
+void Settings::get(bool & res, const string & name)
{
- int n;
- if (!string2Int(querySetting(name, int2String(def)), n) || n < 0)
- throw Error(format("configuration setting `%1%' should have an integer value") % name);
- return n;
-}
-
-
-void overrideSetting(const string & name, const Strings & value)
-{
- if (settingsRead) settings[name] = value;
- settingsCmdline[name] = value;
+ SettingsMap::iterator i = settings.find(name);
+ if (i == settings.end()) return;
+ if (i->second == "true") res = true;
+ else if (i->second == "false") res = false;
+ else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
+ % name % i->second);
}
-void reloadSettings()
+void Settings::get(PathSet & res, const string & name)
{
- settingsRead = false;
- settings.clear();
+ SettingsMap::iterator i = settings.find(name);
+ if (i == settings.end()) return;
+ res.clear();
+ Strings ss = tokenizeString(i->second);
+ res.insert(ss.begin(), ss.end());
}
-void setDefaultsFromEnvironment()
+template<class N> void Settings::get(N & res, const string & name)
{
- /* Setup Nix paths. */
- nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)));
- nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
- 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));
- nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR));
- nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR));
-
- string subs = getEnv("NIX_SUBSTITUTERS", "default");
- if (subs == "default") {
- substituters.push_back(nixLibexecDir + "/nix/substituters/copy-from-other-stores.pl");
- substituters.push_back(nixLibexecDir + "/nix/substituters/download-using-manifests.pl");
- substituters.push_back(nixLibexecDir + "/nix/substituters/download-from-binary-cache.pl");
- } else
- substituters = tokenizeString(subs, ":");
-
- /* Get some settings from the configuration file. */
- thisSystem = querySetting("system", SYSTEM);
- maxBuildJobs = queryIntSetting("build-max-jobs", 1);
- buildCores = queryIntSetting("build-cores", 1);
- maxSilentTime = queryIntSetting("build-max-silent-time", 0);
- buildTimeout = queryIntSetting("build-timeout", 0);
+ SettingsMap::iterator i = settings.find(name);
+ if (i == settings.end()) return;
+ if (!string2Int(i->second, res))
+ throw Error(format("configuration setting `%1%' should have an integer value") % name);
}
-string packSettings()
+string Settings::pack()
{
string s;
- if (!settingsRead) readSettings();
- foreach (Settings::iterator, i, settings) {
- s += i->first; s += '='; s += concatStringsSep(" ", i->second); s += '\n';
+ foreach (SettingsMap::iterator, i, settings) {
+ s += i->first; s += '='; s += i->second; s += '\n';
}
return s;
}
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 30acf59ef..5783d9bf3 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -2,120 +2,189 @@
#include "types.hh"
+#include <map>
+
namespace nix {
-/* Path names. */
+struct Settings {
+
+ Settings();
+
+ void processEnvironment();
+
+ void loadConfFile();
+
+ void set(const string & name, const string & value);
+
+ void update();
+
+ string pack();
+
+ /* The directory where we store sources and derived files. */
+ Path nixStore;
+
+ Path nixDataDir; /* !!! fix */
+
+ /* The directory where we log various operations. */
+ Path nixLogDir;
+
+ /* The directory where state is stored. */
+ Path nixStateDir;
+
+ /* The directory where we keep the SQLite database. */
+ Path nixDBPath;
+
+ /* The directory where configuration files are stored. */
+ Path nixConfDir;
+
+ /* The directory where internal helper programs are stored. */
+ Path nixLibexecDir;
+
+ /* The directory where the main programs are stored. */
+ Path nixBinDir;
+
+ /* Whether to keep temporary directories of failed builds. */
+ bool keepFailed;
+
+ /* Whether to keep building subgoals when a sibling (another
+ subgoal of the same goal) fails. */
+ bool keepGoing;
+
+ /* Whether, if we cannot realise the known closure corresponding
+ to a derivation, we should try to normalise the derivation
+ instead. */
+ bool tryFallback;
+
+ /* Verbosity level for build output. */
+ Verbosity buildVerbosity;
-/* nixStore is the directory where we generally store atomic and
- derived files. */
-extern string nixStore;
+ /* Maximum number of parallel build jobs. 0 means unlimited. */
+ unsigned int maxBuildJobs;
-extern string nixDataDir; /* !!! fix */
+ /* Number of CPU cores to utilize in parallel within a build,
+ i.e. by passing this number to Make via '-j'. 0 means that the
+ number of actual CPU cores on the local host ought to be
+ auto-detected. */
+ unsigned int buildCores;
-/* nixLogDir is the directory where we log various operations. */
-extern string nixLogDir;
+ /* Read-only mode. Don't copy stuff to the store, don't change
+ the database. */
+ bool readOnlyMode;
-/* nixStateDir is the directory where state is stored. */
-extern string nixStateDir;
+ /* The canonical system name, as returned by config.guess. */
+ string thisSystem;
-/* nixDBPath is the path name of our Berkeley DB environment. */
-extern string nixDBPath;
+ /* The maximum time in seconds that a builer can go without
+ producing any output on stdout/stderr before it is killed. 0
+ means infinity. */
+ time_t maxSilentTime;
-/* nixConfDir is the directory where configuration files are
- stored. */
-extern string nixConfDir;
+ /* The maximum duration in seconds that a builder can run. 0
+ means infinity. */
+ time_t buildTimeout;
-/* nixLibexecDir is the directory where internal helper programs are
- stored. */
-extern string nixLibexecDir;
+ /* The substituters. There are programs that can somehow realise
+ a store path without building, e.g., by downloading it or
+ copying it from a CD. */
+ Paths substituters;
-/* nixBinDir is the directory where the main programs are stored. */
-extern string nixBinDir;
+ /* Whether to use build hooks (for distributed builds). Sometimes
+ users want to disable this from the command-line. */
+ bool useBuildHook;
+ /* Whether buildDerivations() should print out lines on stderr in
+ a fixed format to allow its progress to be monitored. Each
+ line starts with a "@". The following are defined:
-/* Misc. global flags. */
+ @ build-started <drvpath> <outpath> <system> <logfile>
+ @ build-failed <drvpath> <outpath> <exitcode> <error text>
+ @ build-succeeded <drvpath> <outpath>
+ @ substituter-started <outpath> <substituter>
+ @ substituter-failed <outpath> <exitcode> <error text>
+ @ substituter-succeeded <outpath>
-/* Whether to keep temporary directories of failed builds. */
-extern bool keepFailed;
+ Best combined with --no-build-output, otherwise stderr might
+ conceivably contain lines in this format printed by the
+ builders. */
+ bool printBuildTrace;
-/* Whether to keep building subgoals when a sibling (another subgoal
- of the same goal) fails. */
-extern bool keepGoing;
+ /* Amount of reserved space for the garbage collector
+ (/nix/var/nix/db/reserved). */
+ off_t reservedSize;
-/* Whether, if we cannot realise the known closure corresponding to a
- derivation, we should try to normalise the derivation instead. */
-extern bool tryFallback;
+ /* Whether SQLite should use fsync. */
+ bool fsyncMetadata;
-/* Verbosity level for build output. */
-extern Verbosity buildVerbosity;
+ /* Whether SQLite should use WAL mode. */
+ bool useSQLiteWAL;
-/* Maximum number of parallel build jobs. 0 means unlimited. */
-extern unsigned int maxBuildJobs;
+ /* Whether to call sync() before registering a path as valid. */
+ bool syncBeforeRegistering;
-/* Number of CPU cores to utilize in parallel within a build, i.e. by passing
- this number to Make via '-j'. 0 means that the number of actual CPU cores on
- the local host ought to be auto-detected. */
-extern unsigned int buildCores;
+ /* Whether to use substitutes. */
+ bool useSubstitutes;
-/* Read-only mode. Don't copy stuff to the store, don't change the
- database. */
-extern bool readOnlyMode;
+ /* The Unix group that contains the build users. */
+ string buildUsersGroup;
-/* The canonical system name, as returned by config.guess. */
-extern string thisSystem;
+ /* Whether to build in chroot. */
+ bool useChroot;
-/* The maximum time in seconds that a builer can go without producing
- any output on stdout/stderr before it is killed. 0 means
- infinity. */
-extern time_t maxSilentTime;
+ /* The directories from the host filesystem to be included in the
+ chroot. */
+ PathSet dirsInChroot;
-/* The maximum duration in seconds that a builder can run. 0 means
- infinity. */
-extern time_t buildTimeout;
+ /* Whether to impersonate a Linux 2.6 machine on newer kernels. */
+ bool impersonateLinux26;
-/* The substituters. There are programs that can somehow realise a
- store path without building, e.g., by downloading it or copying it
- from a CD. */
-extern Paths substituters;
+ /* Whether to store build logs. */
+ bool keepLog;
-/* Whether to use build hooks (for distributed builds). Sometimes
- users want to disable this from the command-line. */
-extern bool useBuildHook;
+ /* Whether to compress logs. */
+ bool compressLog;
-/* Whether buildDerivations() should print out lines on stderr in a
- fixed format to allow its progress to be monitored. Each line
- starts with a "@". The following are defined:
+ /* Whether to cache build failures. */
+ bool cacheFailure;
- @ build-started <drvpath> <outpath> <system> <logfile>
- @ build-failed <drvpath> <outpath> <exitcode> <error text>
- @ build-succeeded <drvpath> <outpath>
- @ substituter-started <outpath> <substituter>
- @ substituter-failed <outpath> <exitcode> <error text>
- @ substituter-succeeded <outpath>
+ /* How often (in seconds) to poll for locks. */
+ unsigned int pollInterval;
- Best combined with --no-build-output, otherwise stderr might
- conceivably contain lines in this format printed by the builders.
-*/
-extern bool printBuildTrace;
+ /* Whether to check if new GC roots can in fact be found by the
+ garbage collector. */
+ bool checkRootReachability;
+ /* Whether the garbage collector should keep outputs of live
+ derivations. */
+ bool gcKeepOutputs;
-Strings querySetting(const string & name, const Strings & def);
+ /* Whether the garbage collector should keep derivers of live
+ paths. */
+ bool gcKeepDerivations;
-string querySetting(const string & name, const string & def);
+ /* Whether to automatically replace files with identical contents
+ with hard links. */
+ bool autoOptimiseStore;
-bool queryBoolSetting(const string & name, bool def);
+ /* Whether to add derivations as a dependency of user environments
+ (to prevent them from being GCed). */
+ bool envKeepDerivations;
-unsigned int queryIntSetting(const string & name, unsigned int def);
+private:
+ typedef std::map<string, string> SettingsMap;
-void overrideSetting(const string & name, const Strings & value);
+ SettingsMap settings;
-void reloadSettings();
+ void get(string & res, const string & name);
+ void get(bool & res, const string & name);
+ void get(PathSet & res, const string & name);
+ template<class N> void get(N & res, const string & name);
+};
-void setDefaultsFromEnvironment();
-string packSettings();
+// FIXME: don't use a global variable.
+extern Settings settings;
}
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index aaa1abb56..f20324d4e 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -181,7 +181,7 @@ struct SQLiteTxn
void checkStoreNotSymlink()
{
if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return;
- Path path = nixStore;
+ Path path = settings.nixStore;
struct stat st;
while (path != "/") {
if (lstat(path.c_str(), &st))
@@ -198,21 +198,21 @@ void checkStoreNotSymlink()
LocalStore::LocalStore(bool reserveSpace)
{
- schemaPath = nixDBPath + "/schema";
+ schemaPath = settings.nixDBPath + "/schema";
- if (readOnlyMode) {
+ if (settings.readOnlyMode) {
openDB(false);
return;
}
/* Create missing state directories if they don't already exist. */
- createDirs(nixStore);
- createDirs(linksDir = nixStore + "/.links");
- Path profilesDir = nixStateDir + "/profiles";
- createDirs(nixStateDir + "/profiles");
- createDirs(nixStateDir + "/temproots");
- createDirs(nixDBPath);
- Path gcRootsDir = nixStateDir + "/gcroots";
+ createDirs(settings.nixStore);
+ createDirs(linksDir = settings.nixStore + "/.links");
+ Path profilesDir = settings.nixStateDir + "/profiles";
+ createDirs(settings.nixStateDir + "/profiles");
+ createDirs(settings.nixStateDir + "/temproots");
+ createDirs(settings.nixDBPath);
+ Path gcRootsDir = settings.nixStateDir + "/gcroots";
if (!pathExists(gcRootsDir)) {
createDirs(gcRootsDir);
if (symlink(profilesDir.c_str(), (gcRootsDir + "/profiles").c_str()) == -1)
@@ -226,13 +226,12 @@ LocalStore::LocalStore(bool reserveSpace)
needed, we reserve some dummy space that we can free just
before doing a garbage collection. */
try {
- Path reservedPath = nixDBPath + "/reserved";
+ Path reservedPath = settings.nixDBPath + "/reserved";
if (reserveSpace) {
- int reservedSize = queryIntSetting("gc-reserved-space", 1024 * 1024);
struct stat st;
if (stat(reservedPath.c_str(), &st) == -1 ||
- st.st_size != reservedSize)
- writeFile(reservedPath, string(reservedSize, 'X'));
+ st.st_size != settings.reservedSize)
+ writeFile(reservedPath, string(settings.reservedSize, 'X'));
}
else
deletePath(reservedPath);
@@ -242,11 +241,11 @@ LocalStore::LocalStore(bool reserveSpace)
/* Acquire the big fat lock in shared mode to make sure that no
schema upgrade is in progress. */
try {
- Path globalLockPath = nixDBPath + "/big-lock";
+ Path globalLockPath = settings.nixDBPath + "/big-lock";
globalLock = openLockFile(globalLockPath.c_str(), true);
} catch (SysError & e) {
if (e.errNo != EACCES) throw;
- readOnlyMode = true;
+ settings.readOnlyMode = true;
openDB(false);
return;
}
@@ -325,7 +324,7 @@ int LocalStore::getSchema()
void LocalStore::openDB(bool create)
{
/* Open the Nix database. */
- if (sqlite3_open_v2((nixDBPath + "/db.sqlite").c_str(), &db.db,
+ if (sqlite3_open_v2((settings.nixDBPath + "/db.sqlite").c_str(), &db.db,
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
throw Error("cannot open SQLite database");
@@ -342,13 +341,13 @@ void LocalStore::openDB(bool create)
should be safe enough. If the user asks for it, don't sync at
all. This can cause database corruption if the system
crashes. */
- string syncMode = queryBoolSetting("fsync-metadata", true) ? "normal" : "off";
+ string syncMode = settings.fsyncMetadata ? "normal" : "off";
if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 0, 0, 0) != SQLITE_OK)
throwSQLiteError(db, "setting synchronous mode");
/* Set the SQLite journal mode. WAL mode is fastest, so it's the
default. */
- string mode = queryBoolSetting("use-sqlite-wal", true) ? "wal" : "truncate";
+ string mode = settings.useSQLiteWAL ? "wal" : "truncate";
string prevMode;
{
SQLiteStmt stmt;
@@ -890,7 +889,7 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart)
SQLiteTxn txn(db);
- Path prefix = nixStore + "/" + hashPart;
+ Path prefix = settings.nixStore + "/" + hashPart;
SQLiteStmtUse use(stmtQueryPathFromHashPart);
stmtQueryPathFromHashPart.bind(prefix);
@@ -933,7 +932,7 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter &
/* Pass configuration options (including those overriden
with --option) to the substituter. */
- setenv("_NIX_OPTIONS", packSettings().c_str(), 1);
+ setenv("_NIX_OPTIONS", settings.pack().c_str(), 1);
fromPipe.readSide.close();
toPipe.writeSide.close();
@@ -969,7 +968,7 @@ template<class T> T getIntLine(int fd)
PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
{
PathSet res;
- foreach (Paths::iterator, i, substituters) {
+ foreach (Paths::iterator, i, settings.substituters) {
if (res.size() == paths.size()) break;
RunningSubstituter & run(runningSubstituters[*i]);
startSubstituter(*i, run);
@@ -1023,7 +1022,7 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
SubstitutablePathInfos & infos)
{
PathSet todo = paths;
- foreach (Paths::iterator, i, substituters) {
+ foreach (Paths::iterator, i, settings.substituters) {
if (todo.empty()) break;
querySubstitutablePathInfos(*i, todo, infos);
}
@@ -1046,11 +1045,10 @@ void LocalStore::registerValidPath(const ValidPathInfo & info)
void LocalStore::registerValidPaths(const ValidPathInfos & infos)
{
- /* sqlite will fsync by default, but the new valid paths may not be fsync-ed.
+ /* SQLite will fsync by default, but the new valid paths may not be fsync-ed.
* So some may want to fsync them before registering the validity, at the
* expense of some speed of the path registering operation. */
- if (queryBoolSetting("sync-before-registering", false))
- sync();
+ if (settings.syncBeforeRegistering) sync();
while (1) {
try {
@@ -1294,7 +1292,7 @@ void LocalStore::exportPath(const Path & path, bool sign,
Path hashFile = tmpDir + "/hash";
writeFile(hashFile, printHash(hash));
- Path secretKey = nixConfDir + "/signing-key.sec";
+ Path secretKey = settings.nixConfDir + "/signing-key.sec";
checkSecrecy(secretKey);
Strings args;
@@ -1340,7 +1338,7 @@ Path LocalStore::createTempDirInStore()
/* There is a slight possibility that `tmpDir' gets deleted by
the GC between createTempDir() and addTempRoot(), so repeat
until `tmpDir' exists. */
- tmpDir = createTempDir(nixStore);
+ tmpDir = createTempDir(settings.nixStore);
addTempRoot(tmpDir);
} while (!pathExists(tmpDir));
return tmpDir;
@@ -1392,7 +1390,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
args.push_back("rsautl");
args.push_back("-verify");
args.push_back("-inkey");
- args.push_back(nixConfDir + "/signing-key.pub");
+ args.push_back(settings.nixConfDir + "/signing-key.pub");
args.push_back("-pubin");
args.push_back("-in");
args.push_back(sigFile);
@@ -1501,7 +1499,7 @@ void LocalStore::verifyStore(bool checkContents)
/* Acquire the global GC lock to prevent a garbage collection. */
AutoCloseFD fdGCLock = openGCLock(ltWrite);
- Paths entries = readDirectory(nixStore);
+ Paths entries = readDirectory(settings.nixStore);
PathSet store(entries.begin(), entries.end());
/* Check whether all valid paths actually exist. */
@@ -1611,9 +1609,9 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
PathSet LocalStore::queryValidPathsOld()
{
PathSet paths;
- Strings entries = readDirectory(nixDBPath + "/info");
+ Strings entries = readDirectory(settings.nixDBPath + "/info");
foreach (Strings::iterator, i, entries)
- if (i->at(0) != '.') paths.insert(nixStore + "/" + *i);
+ if (i->at(0) != '.') paths.insert(settings.nixStore + "/" + *i);
return paths;
}
@@ -1625,7 +1623,7 @@ ValidPathInfo LocalStore::queryPathInfoOld(const Path & path)
/* Read the info file. */
string baseName = baseNameOf(path);
- Path infoFile = (format("%1%/info/%2%") % nixDBPath % baseName).str();
+ Path infoFile = (format("%1%/info/%2%") % settings.nixDBPath % baseName).str();
if (!pathExists(infoFile))
throw Error(format("path `%1%' is not valid") % path);
string info = readFile(infoFile);
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 4761658ed..7cf9fc18d 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -75,7 +75,7 @@ struct SQLiteStmt
void bind64(long long value);
void bind();
};
-
+
class LocalStore : public StoreAPI
{
@@ -84,7 +84,7 @@ private:
RunningSubstituters runningSubstituters;
Path linksDir;
-
+
public:
/* Initialise the local store, upgrading the schema if
@@ -92,15 +92,15 @@ public:
LocalStore(bool reserveSpace = true);
~LocalStore();
-
+
/* Implementations of abstract store API methods. */
-
+
bool isValidPath(const Path & path);
PathSet queryValidPaths(const PathSet & paths);
-
+
PathSet queryAllValidPaths();
-
+
ValidPathInfo queryPathInfo(const Path & path);
Hash queryPathHash(const Path & path);
@@ -120,17 +120,17 @@ public:
PathSet queryDerivationOutputs(const Path & path);
StringSet queryDerivationOutputNames(const Path & path);
-
+
Path queryPathFromHashPart(const string & hashPart);
-
+
PathSet querySubstitutablePaths(const PathSet & paths);
void querySubstitutablePathInfos(const Path & substituter,
PathSet & paths, SubstitutablePathInfos & infos);
-
+
void querySubstitutablePathInfos(const PathSet & paths,
SubstitutablePathInfos & infos);
-
+
Path addToStore(const Path & srcPath,
bool recursive = true, HashType hashAlgo = htSHA256,
PathFilter & filter = defaultPathFilter);
@@ -149,7 +149,7 @@ public:
Sink & sink);
Paths importPaths(bool requireSignature, Source & source);
-
+
void buildPaths(const PathSet & paths);
void ensurePath(const Path & path);
@@ -157,7 +157,7 @@ public:
void addTempRoot(const Path & path);
void addIndirectRoot(const Path & path);
-
+
void syncWithGC();
Roots findRoots();
@@ -170,7 +170,7 @@ public:
/* Optimise a single store path. */
void optimisePath(const Path & path);
-
+
/* Check the integrity of the Nix store. */
void verifyStore(bool checkContents);
@@ -229,18 +229,18 @@ private:
unsigned long long queryValidPathId(const Path & path);
unsigned long long addValidPath(const ValidPathInfo & info, bool checkOutputs = true);
-
+
void addReference(unsigned long long referrer, unsigned long long reference);
-
+
void appendReferrer(const Path & from, const Path & to, bool lock);
-
+
void rewriteReferrers(const Path & path, bool purge, PathSet referrers);
void invalidatePath(const Path & path);
/* Delete a path from the Nix store. */
void invalidatePathChecked(const Path & path);
-
+
void verifyPath(const Path & path, const PathSet & store,
PathSet & done, PathSet & validPaths);
@@ -253,14 +253,14 @@ private:
struct GCState;
void deleteGarbage(GCState & state, const Path & path);
-
+
bool tryToDelete(GCState & state, const Path & path);
-
+
bool isActiveTempFile(const GCState & state,
const Path & path, const string & suffix);
-
+
int openGCLock(LockType lockType);
-
+
void removeUnusedLinks();
void startSubstituter(const Path & substituter,
@@ -269,7 +269,7 @@ private:
Path createTempDirInStore();
Path importPath(bool requireSignature, Source & source);
-
+
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
void optimisePath_(OptimiseStats & stats, const Path & path);
@@ -290,9 +290,6 @@ void canonicalisePathMetaData(const Path & path, bool recurse);
MakeError(PathInUse, Error);
-/* Whether we are in build users mode. */
-bool haveBuildUsers();
-
/* Whether we are root. */
bool amPrivileged();
@@ -305,5 +302,5 @@ void deletePathWrapped(const Path & path,
unsigned long long & bytesFreed, unsigned long long & blocksFreed);
void deletePathWrapped(const Path & path);
-
+
}
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index aa5f6ff72..3ce300e30 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -52,10 +52,8 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
unsigned long long & downloadSize, unsigned long long & narSize)
{
downloadSize = narSize = 0;
-
- PathSet todo(targets.begin(), targets.end()), done;
- bool useSubstitutes = queryBoolSetting("build-use-substitutes", true);
+ PathSet todo(targets.begin(), targets.end()), done;
/* Getting substitute info has high latency when using the binary
cache substituter. Thus it's essential to do substitute
@@ -77,7 +75,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
*/
while (!todo.empty()) {
-
+
PathSet query, todoDrv, todoNonDrv;
foreach (PathSet::iterator, i, todo) {
@@ -96,9 +94,9 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
foreach (DerivationOutputs::iterator, j, drv.outputs)
if (!store.isValidPath(j->second.path)) invalid.insert(j->second.path);
if (invalid.empty()) continue;
-
+
todoDrv.insert(*i);
- if (useSubstitutes) query.insert(invalid.begin(), invalid.end());
+ if (settings.useSubstitutes) query.insert(invalid.begin(), invalid.end());
}
else {
@@ -109,7 +107,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
}
todo.clear();
-
+
SubstitutablePathInfos infos;
store.querySubstitutablePathInfos(query, infos);
@@ -118,7 +116,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
Derivation drv = derivationFromPath(store, *i);
bool mustBuild = false;
- if (useSubstitutes) {
+ if (settings.useSubstitutes) {
foreach (DerivationOutputs::iterator, j, drv.outputs)
if (!store.isValidPath(j->second.path) &&
infos.find(j->second.path) == infos.end())
@@ -135,7 +133,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
foreach (DerivationOutputs::iterator, i, drv.outputs)
todoNonDrv.insert(i->second.path);
}
-
+
foreach (PathSet::iterator, i, todoNonDrv) {
done.insert(*i);
SubstitutablePathInfos::iterator info = infos.find(*i);
@@ -150,22 +148,22 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
}
}
-
+
static void dfsVisit(StoreAPI & store, const PathSet & paths,
const Path & path, PathSet & visited, Paths & sorted,
PathSet & parents)
{
if (parents.find(path) != parents.end())
throw BuildError(format("cycle detected in the references of `%1%'") % path);
-
+
if (visited.find(path) != visited.end()) return;
visited.insert(path);
parents.insert(path);
-
+
PathSet references;
if (store.isValidPath(path))
store.queryReferences(path, references);
-
+
foreach (PathSet::iterator, i, references)
/* Don't traverse into paths that don't exist. That can
happen due to substitutes for non-existent paths. */
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 84a72604b..e08ee1784 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -17,7 +17,7 @@ static void makeWritable(const Path & path)
{
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(format("getting attributes of path `%1%'") % path);
if (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode)) makeMutable(path);
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
throw SysError(format("changing writability of `%1%'") % path);
@@ -53,15 +53,15 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
{
struct stat st;
if (lstat(path.c_str(), &st))
- throw SysError(format("getting attributes of path `%1%'") % path);
+ throw SysError(format("getting attributes of path `%1%'") % path);
if (S_ISDIR(st.st_mode)) {
Strings names = readDirectory(path);
- foreach (Strings::iterator, i, names)
- optimisePath_(stats, path + "/" + *i);
+ foreach (Strings::iterator, i, names)
+ optimisePath_(stats, path + "/" + *i);
return;
}
-
+
/* We can hard link regular files and maybe symlinks. */
if (!S_ISREG(st.st_mode)
#if CAN_LINK_SYMLINK
@@ -69,7 +69,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
&& !S_ISLNK(st.st_mode)
#endif
) return;
-
+
/* Sometimes SNAFUs can cause files in the Nix store to be
modified, in particular when running programs as root under
NixOS (example: $fontconfig/var/cache being modified). Skip
@@ -110,25 +110,25 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path)
current file with a hard link to that file. */
struct stat stLink;
if (lstat(linkPath.c_str(), &stLink))
- throw SysError(format("getting attributes of path `%1%'") % linkPath);
-
+ throw SysError(format("getting attributes of path `%1%'") % linkPath);
+
stats.sameContents++;
if (st.st_ino == stLink.st_ino) {
printMsg(lvlDebug, format("`%1%' is already linked to `%2%'") % path % linkPath);
return;
}
-
+
printMsg(lvlTalkative, format("linking `%1%' to `%2%'") % path % linkPath);
Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
- % nixStore % getpid() % rand()).str();
+ % settings.nixStore % getpid() % rand()).str();
/* Make the containing directory writable, but only if it's not
the store itself (we don't want or need to mess with its
permissions). */
bool mustToggle = !isStorePath(path);
if (mustToggle) makeWritable(dirOf(path));
-
+
/* When we're done, make the directory read-only again and reset
its timestamp back to 0. */
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
@@ -192,10 +192,8 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
void LocalStore::optimisePath(const Path & path)
{
- if (queryBoolSetting("auto-optimise-store", true)) {
- OptimiseStats stats;
- optimisePath_(stats, path);
- }
+ OptimiseStats stats;
+ if (settings.autoOptimiseStore) optimisePath_(stats, path);
}
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 5910ffd53..c67e53bfb 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -100,7 +100,7 @@ void RemoteStore::forkSlave()
/* Start the worker. */
Path worker = getEnv("NIX_WORKER");
if (worker == "")
- worker = nixBinDir + "/nix-worker";
+ worker = settings.nixBinDir + "/nix-worker";
child = fork();
@@ -142,7 +142,7 @@ void RemoteStore::connectToDaemon()
if (fdSocket == -1)
throw SysError("cannot create Unix domain socket");
- string socketPath = nixStateDir + DEFAULT_SOCKET_PATH;
+ string socketPath = settings.nixStateDir + DEFAULT_SOCKET_PATH;
/* Urgh, sockaddr_un allows path names of only 108 characters. So
chdir to the socket directory so that we can pass a relative
@@ -184,23 +184,23 @@ RemoteStore::~RemoteStore()
void RemoteStore::setOptions()
{
writeInt(wopSetOptions, to);
- writeInt(keepFailed, to);
- writeInt(keepGoing, to);
- writeInt(tryFallback, to);
+ writeInt(settings.keepFailed, to);
+ writeInt(settings.keepGoing, to);
+ writeInt(settings.tryFallback, to);
writeInt(verbosity, to);
- writeInt(maxBuildJobs, to);
- writeInt(maxSilentTime, to);
+ writeInt(settings.maxBuildJobs, to);
+ writeInt(settings.maxSilentTime, to);
if (GET_PROTOCOL_MINOR(daemonVersion) >= 2)
- writeInt(useBuildHook, to);
+ writeInt(settings.useBuildHook, to);
if (GET_PROTOCOL_MINOR(daemonVersion) >= 4) {
- writeInt(buildVerbosity, to);
+ writeInt(settings.buildVerbosity, to);
writeInt(logType, to);
- writeInt(printBuildTrace, to);
+ writeInt(settings.printBuildTrace, to);
}
if (GET_PROTOCOL_MINOR(daemonVersion) >= 6)
- writeInt(buildCores, to);
+ writeInt(settings.buildCores, to);
if (GET_PROTOCOL_MINOR(daemonVersion) >= 10)
- writeInt(queryBoolSetting("build-use-substitutes", true), to);
+ writeInt(settings.useSubstitutes, to);
processStderr();
}
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index b64988268..6f81a9aab 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -19,16 +19,16 @@ GCOptions::GCOptions()
bool isInStore(const Path & path)
{
return path[0] == '/'
- && string(path, 0, nixStore.size()) == nixStore
- && path.size() >= nixStore.size() + 2
- && path[nixStore.size()] == '/';
+ && string(path, 0, settings.nixStore.size()) == settings.nixStore
+ && path.size() >= settings.nixStore.size() + 2
+ && path[settings.nixStore.size()] == '/';
}
bool isStorePath(const Path & path)
{
return isInStore(path)
- && path.find('/', nixStore.size() + 1) == Path::npos;
+ && path.find('/', settings.nixStore.size() + 1) == Path::npos;
}
@@ -43,7 +43,7 @@ Path toStorePath(const Path & path)
{
if (!isInStore(path))
throw Error(format("path `%1%' is not in the Nix store") % path);
- Path::size_type slash = path.find('/', nixStore.size() + 1);
+ Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
if (slash == Path::npos)
return path;
else
@@ -74,7 +74,7 @@ Path followLinksToStorePath(const Path & path)
string storePathToName(const Path & path)
{
assertStorePath(path);
- return string(path, nixStore.size() + 34);
+ return string(path, settings.nixStore.size() + 34);
}
@@ -173,11 +173,11 @@ Path makeStorePath(const string & type,
{
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
string s = type + ":sha256:" + printHash(hash) + ":"
- + nixStore + ":" + name;
+ + settings.nixStore + ":" + name;
checkStoreName(name);
- return nixStore + "/"
+ return settings.nixStore + "/"
+ printHash32(compressHash(hashString(htSHA256, s), 20))
+ "-" + name;
}
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index f06f23dad..475bdd366 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -55,7 +55,6 @@ struct Globals
EvalState state;
bool dryRun;
bool preserveInstalled;
- bool keepDerivations;
string forceName;
bool prebuiltOnly;
};
@@ -266,8 +265,8 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
if (k != newest.end()) {
d = j->first.system == k->second.first.system ? 0 :
- j->first.system == thisSystem ? 1 :
- k->second.first.system == thisSystem ? -1 : 0;
+ j->first.system == settings.thisSystem ? 1 :
+ k->second.first.system == settings.thisSystem ? -1 : 0;
if (d == 0)
d = comparePriorities(state, j->first, k->second.first);
if (d == 0)
@@ -498,7 +497,7 @@ static void installDerivations(Globals & globals,
if (globals.dryRun) return;
if (createUserEnv(globals.state, allElems,
- profile, globals.keepDerivations, lockToken)) break;
+ profile, settings.envKeepDerivations, lockToken)) break;
}
}
@@ -605,7 +604,7 @@ static void upgradeDerivations(Globals & globals,
if (globals.dryRun) return;
if (createUserEnv(globals.state, newElems,
- globals.profile, globals.keepDerivations, lockToken)) break;
+ globals.profile, settings.envKeepDerivations, lockToken)) break;
}
}
@@ -672,7 +671,7 @@ static void opSetFlag(Globals & globals,
/* Write the new user environment. */
if (createUserEnv(globals.state, installedElems,
- globals.profile, globals.keepDerivations, lockToken)) break;
+ globals.profile, settings.envKeepDerivations, lockToken)) break;
}
}
@@ -740,7 +739,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
if (globals.dryRun) return;
if (createUserEnv(globals.state, newElems,
- profile, globals.keepDerivations, lockToken)) break;
+ profile, settings.envKeepDerivations, lockToken)) break;
}
}
@@ -869,7 +868,7 @@ static void opQuery(Globals & globals,
enum { sInstalled, sAvailable } source = sInstalled;
- readOnlyMode = true; /* makes evaluation a bit faster */
+ settings.readOnlyMode = true; /* makes evaluation a bit faster */
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
@@ -1262,9 +1261,6 @@ void run(Strings args)
globals.preserveInstalled = false;
globals.prebuiltOnly = false;
- globals.keepDerivations =
- queryBoolSetting("env-keep-derivations", false);
-
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
@@ -1331,7 +1327,7 @@ void run(Strings args)
Path profileLink = getHomeDir() + "/.nix-profile";
globals.profile = pathExists(profileLink)
? absPath(readLink(profileLink), dirOf(profileLink))
- : canonPath(nixStateDir + "/profiles/default");
+ : canonPath(settings.nixStateDir + "/profiles/default");
}
store = openStore();
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index d86c9fc84..270b4ddc2 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -94,11 +94,11 @@ void run(Strings args)
if (arg == "-")
readStdin = true;
else if (arg == "--eval-only") {
- readOnlyMode = true;
+ settings.readOnlyMode = true;
evalOnly = true;
}
else if (arg == "--parse-only") {
- readOnlyMode = true;
+ settings.readOnlyMode = true;
parseOnly = evalOnly = true;
}
else if (arg == "--find-file")
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 941301d2e..5ada79713 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -47,7 +47,7 @@ LocalStore & ensureLocalStore()
static Path useDeriver(Path path)
-{
+{
if (!isDerivation(path)) {
path = store->queryDeriver(path);
if (path == "")
@@ -89,18 +89,18 @@ static PathSet realisePath(const Path & path)
static void opRealise(Strings opFlags, Strings opArgs)
{
bool dryRun = false;
-
+
foreach (Strings::iterator, i, opFlags)
if (*i == "--dry-run") dryRun = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
foreach (Strings::iterator, i, opArgs)
*i = followLinksToStorePath(*i);
-
+
printMissing(*store, PathSet(opArgs.begin(), opArgs.end()));
-
+
if (dryRun) return;
-
+
/* Build all paths at the same time to exploit parallelism. */
PathSet paths(opArgs.begin(), opArgs.end());
store->buildPaths(paths);
@@ -128,7 +128,7 @@ static void opAdd(Strings opFlags, Strings opArgs)
static void opAddFixed(Strings opFlags, Strings opArgs)
{
bool recursive = false;
-
+
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--recursive") recursive = true;
@@ -136,7 +136,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
if (opArgs.empty())
throw UsageError("first argument must be hash algorithm");
-
+
HashType hashAlgo = parseHashType(opArgs.front());
opArgs.pop_front();
@@ -149,7 +149,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
static void opPrintFixedPath(Strings opFlags, Strings opArgs)
{
bool recursive = false;
-
+
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--recursive") recursive = true;
@@ -157,7 +157,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
if (opArgs.size() != 3)
throw UsageError(format("`--print-fixed-path' requires three arguments"));
-
+
Strings::iterator i = opArgs.begin();
HashType hashAlgo = parseHashType(*i++);
string hash = *i++;
@@ -205,12 +205,12 @@ static void printTree(const Path & path,
PathSet references;
store->queryReferences(path, references);
-
-#if 0
+
+#if 0
for (PathSet::iterator i = drv.inputSrcs.begin();
i != drv.inputSrcs.end(); ++i)
cout << format("%1%%2%\n") % (tailPad + treeConn) % *i;
-#endif
+#endif
/* Topologically sort under the relation A < B iff A \in
closure(B). That is, if derivation A is an (possibly indirect)
@@ -266,7 +266,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
else throw UsageError(format("unknown flag `%1%'") % *i);
switch (query) {
-
+
case qOutputs: {
foreach (Strings::iterator, i, opArgs) {
*i = followLinksToStorePath(*i);
@@ -293,7 +293,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
}
}
Paths sorted = topoSortPaths(*store, paths);
- for (Paths::reverse_iterator i = sorted.rbegin();
+ for (Paths::reverse_iterator i = sorted.rbegin();
i != sorted.rend(); ++i)
cout << format("%s\n") % *i;
break;
@@ -328,7 +328,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
if (query == qHash) {
assert(info.hash.type == htSHA256);
cout << format("sha256:%1%\n") % printHash32(info.hash);
- } else if (query == qSize)
+ } else if (query == qSize)
cout << format("%1%\n") % info.narSize;
}
}
@@ -340,7 +340,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
printTree(followLinksToStorePath(*i), "", "", done);
break;
}
-
+
case qGraph: {
PathSet roots;
foreach (Strings::iterator, i, opArgs) {
@@ -366,7 +366,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
cout << format("%1%\n") % followLinksToStorePath(*i);
break;
}
-
+
case qRoots: {
PathSet referrers;
foreach (Strings::iterator, i, opArgs) {
@@ -380,7 +380,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
cout << format("%1%\n") % i->first;
break;
}
-
+
default:
abort();
}
@@ -426,9 +426,9 @@ static void opReadLog(Strings opFlags, Strings opArgs)
foreach (Strings::iterator, i, opArgs) {
Path path = useDeriver(followLinksToStorePath(*i));
-
+
Path logPath = (format("%1%/%2%/%3%") %
- nixLogDir % drvsLogDir % baseNameOf(path)).str();
+ settings.nixLogDir % drvsLogDir % baseNameOf(path)).str();
Path logBz2Path = logPath + ".bz2";
if (pathExists(logPath)) {
@@ -454,7 +454,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
} while (err != BZ_STREAM_END);
BZ2_bzReadClose(&err, bz);
}
-
+
else throw Error(format("build log of derivation `%1%' is not available") % path);
}
}
@@ -474,7 +474,7 @@ static void opDumpDB(Strings opFlags, Strings opArgs)
static void registerValidity(bool reregister, bool hashGiven, bool canonicalise)
{
ValidPathInfos infos;
-
+
while (1) {
ValidPathInfo info = decodeValidPathInfo(cin, hashGiven);
if (info.path == "") break;
@@ -508,7 +508,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
{
bool reregister = false; // !!! maybe this should be the default
bool hashGiven = false;
-
+
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--reregister") reregister = true;
@@ -524,7 +524,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
static void opCheckValidity(Strings opFlags, Strings opArgs)
{
bool printInvalid = false;
-
+
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--print-invalid") printInvalid = true;
@@ -551,13 +551,13 @@ static string showBytes(unsigned long long bytes, unsigned long long blocks)
}
-struct PrintFreed
+struct PrintFreed
{
bool show;
const GCResults & results;
PrintFreed(bool show, const GCResults & results)
: show(show), results(results) { }
- ~PrintFreed()
+ ~PrintFreed()
{
if (show)
cout << format("%1% store paths deleted, %2% freed\n")
@@ -572,9 +572,9 @@ static void opGC(Strings opFlags, Strings opArgs)
bool printRoots = false;
GCOptions options;
options.action = GCOptions::gcDeleteDead;
-
+
GCResults results;
-
+
/* Do what? */
foreach (Strings::iterator, i, opFlags)
if (*i == "--print-roots") printRoots = true;
@@ -613,14 +613,14 @@ static void opDelete(Strings opFlags, Strings opArgs)
{
GCOptions options;
options.action = GCOptions::gcDeleteSpecific;
-
+
foreach (Strings::iterator, i, opFlags)
if (*i == "--ignore-liveness") options.ignoreLiveness = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
foreach (Strings::iterator, i, opArgs)
options.pathsToDelete.insert(followLinksToStorePath(*i));
-
+
GCResults results;
PrintFreed freed(true, results);
store->collectGarbage(options, results);
@@ -671,9 +671,9 @@ static void opImport(Strings opFlags, Strings opArgs)
foreach (Strings::iterator, i, opFlags)
if (*i == "--require-signature") requireSignature = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
-
+
if (!opArgs.empty()) throw UsageError("no arguments expected");
-
+
FdSource source(STDIN_FILENO);
Paths paths = store->importPaths(requireSignature, source);
@@ -700,12 +700,12 @@ static void opVerify(Strings opFlags, Strings opArgs)
throw UsageError("no arguments expected");
bool checkContents = false;
-
+
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--check-contents") checkContents = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
-
+
ensureLocalStore().verifyStore(checkContents);
}
@@ -844,7 +844,7 @@ void run(Strings args)
}
else if (arg == "--indirect")
indirectRoot = true;
- else if (arg[0] == '-') {
+ else if (arg[0] == '-') {
opFlags.push_back(arg);
if (arg == "--max-freed" || arg == "--max-links" || arg == "--max-atime") { /* !!! hack */
if (i != args.end()) opFlags.push_back(*i++);
diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc
index 09800c160..84ad68904 100644
--- a/src/nix-worker/nix-worker.cc
+++ b/src/nix-worker/nix-worker.cc
@@ -527,27 +527,23 @@ static void performOp(unsigned int clientVersion,
}
case wopSetOptions: {
- keepFailed = readInt(from) != 0;
- keepGoing = readInt(from) != 0;
- tryFallback = readInt(from) != 0;
+ settings.keepFailed = readInt(from) != 0;
+ settings.keepGoing = readInt(from) != 0;
+ settings.tryFallback = readInt(from) != 0;
verbosity = (Verbosity) readInt(from);
- maxBuildJobs = readInt(from);
- maxSilentTime = readInt(from);
+ settings.maxBuildJobs = readInt(from);
+ settings.maxSilentTime = readInt(from);
if (GET_PROTOCOL_MINOR(clientVersion) >= 2)
- useBuildHook = readInt(from) != 0;
+ settings.useBuildHook = readInt(from) != 0;
if (GET_PROTOCOL_MINOR(clientVersion) >= 4) {
- buildVerbosity = (Verbosity) readInt(from);
+ settings.buildVerbosity = (Verbosity) readInt(from);
logType = (LogType) readInt(from);
- printBuildTrace = readInt(from) != 0;
+ settings.printBuildTrace = readInt(from) != 0;
}
if (GET_PROTOCOL_MINOR(clientVersion) >= 6)
- buildCores = readInt(from);
- if (GET_PROTOCOL_MINOR(clientVersion) >= 10) {
- int x = readInt(from);
- Strings ss;
- ss.push_back(x == 0 ? "false" : "true");
- overrideSetting("build-use-substitutes", ss);
- }
+ settings.buildCores = readInt(from);
+ if (GET_PROTOCOL_MINOR(clientVersion) >= 10)
+ settings.useSubstitutes = readInt(from) != 0;
startWork();
stopWork();
break;
@@ -768,7 +764,7 @@ static void daemonLoop()
if (fdSocket == -1)
throw SysError("cannot create Unix domain socket");
- string socketPath = nixStateDir + DEFAULT_SOCKET_PATH;
+ string socketPath = settings.nixStateDir + DEFAULT_SOCKET_PATH;
createDirs(dirOf(socketPath));
@@ -867,10 +863,6 @@ static void daemonLoop()
strncpy(argvSaved[1], processName.c_str(), strlen(argvSaved[1]));
}
- /* Since the daemon can be long-running, the
- settings may have changed. So force a reload. */
- reloadSettings();
-
/* Handle the connection. */
from.fd = remote;
to.fd = remote;