diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-11-09T17·00+0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-11-09T17·00+0100 |
commit | ea89df2b76811505239b508a570ac9c0ea591038 (patch) | |
tree | 7b11ea7186ad2b73bf12ebb2e51e7238a052db85 /src/libstore | |
parent | 48c19c4633b1443015531ee3032b16b29b0a92f9 (diff) |
Use vfork() instead of fork() if available
Hopefully this reduces the chance of hitting ‘unable to fork: Cannot allocate memory’ errors. vfork() is used for everything except starting builders.
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/build.cc | 27 | ||||
-rw-r--r-- | src/libstore/local-store.cc | 21 | ||||
-rw-r--r-- | src/libstore/local-store.hh | 4 |
3 files changed, 33 insertions, 19 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 6def0c1c5481..3e67e55d4a22 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -665,7 +665,7 @@ HookInstance::HookInstance() builderOut.create(); /* Fork the hook. */ - pid = fork(); + pid = maybeVfork(); switch (pid) { case -1: @@ -2662,8 +2662,19 @@ void SubstitutionGoal::tryToRun() if (pathExists(destPath)) deletePathWrapped(destPath); + worker.store.setSubstituterEnv(); + + /* Fill in the arguments. */ + Strings args; + args.push_back(baseNameOf(sub)); + args.push_back("--substitute"); + args.push_back(storePath); + args.push_back(destPath); + const char * * argArr = strings2CharPtrs(args); + /* Fork the substitute program. */ - pid = fork(); + pid = maybeVfork(); + switch (pid) { case -1: @@ -2677,18 +2688,6 @@ void SubstitutionGoal::tryToRun() if (dup2(outPipe.writeSide, STDOUT_FILENO) == -1) throw SysError("cannot dup output pipe into stdout"); - /* Pass configuration options (including those overriden - with --option) to the substituter. */ - setenv("_NIX_OPTIONS", settings.pack().c_str(), 1); - - /* Fill in the arguments. */ - Strings args; - args.push_back(baseNameOf(sub)); - args.push_back("--substitute"); - args.push_back(storePath); - args.push_back(destPath); - const char * * argArr = strings2CharPtrs(args); - execv(sub.c_str(), (char * *) argArr); throw SysError(format("executing `%1%'") % sub); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index d6cdd10d6f88..b4fc64d712fa 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -202,6 +202,7 @@ void checkStoreNotSymlink() LocalStore::LocalStore(bool reserveSpace) + : didSetSubstituterEnv(false) { schemaPath = settings.nixDBPath + "/schema"; @@ -943,6 +944,18 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart) } +void LocalStore::setSubstituterEnv() +{ + if (didSetSubstituterEnv) return; + + /* Pass configuration options (including those overriden with + --option) to substituters. */ + setenv("_NIX_OPTIONS", settings.pack().c_str(), 1); + + didSetSubstituterEnv = true; +} + + void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run) { if (run.pid != -1) return; @@ -955,7 +968,9 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & fromPipe.create(); errorPipe.create(); - run.pid = fork(); + setSubstituterEnv(); + + run.pid = maybeVfork(); switch (run.pid) { @@ -964,10 +979,6 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & case 0: /* child */ try { - /* Pass configuration options (including those overriden - with --option) to the substituter. */ - setenv("_NIX_OPTIONS", settings.pack().c_str(), 1); - if (dup2(toPipe.readSide, STDIN_FILENO) == -1) throw SysError("dupping stdin"); if (dup2(fromPipe.writeSide, STDOUT_FILENO) == -1) diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 8d745cfb835e..ebf3f6e2b4e7 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -208,6 +208,8 @@ public: void markContentsGood(const Path & path); + void setSubstituterEnv(); + private: Path schemaPath; @@ -238,6 +240,8 @@ private: /* Cache for pathContentsGood(). */ std::map<Path, bool> pathContentsGoodCache; + bool didSetSubstituterEnv; + int getSchema(); void openDB(bool create); |