diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2015-07-02 23:37:29 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2015-07-03 00:30:55 +0200 |
| commit | 322eeb87d0e5bb608ae1c176611a50297c93cbe8 (patch) | |
| tree | ecc0c32c8365b66021be9a26b77a084efc179be3 | |
| parent | d2cef629fd5856540f6e1edf8f9d2131ec7a6942 (diff) | |
Merge branch 'nix'.
This is a squashed commit of the following:
commit 0dccab9f417b406f5d4aedc81900fc7b2f16c9f6
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Thu Jul 2 00:30:16 2015 +0200
Typo
commit 2cd28517b13524c242c7758783b0b2d8250fdded
Author: Ludovic Courtès <ludo@gnu.org>
Date: Wed Jul 1 14:56:34 2015 +0200
Preserve supplementary groups of build users
The following patch is an attempt to address this bug (see
<http://bugs.gnu.org/18994>) by preserving the supplementary groups of
build users in the build environment.
In practice, I would expect that supplementary groups would contain only
one or two groups: the build users group, and possibly the “kvm” group.
[Changed &at(0) to data() and removed tabs - Eelco]
commit 6e38685ef65284093df79ebe7378bac33b0e7e5d
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Tue Jun 30 21:41:26 2015 +0200
GC: Handle ENOSPC creating/moving to the trash directory
Issue #564.
commit 5e0a9ae2e25a1016389f4893a6ed6682aadcf51d
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Mon Jun 22 15:54:55 2015 +0200
Use posix_fallocate to create /nix/var/nix/db/reserved
commit 4e5ab98d6d14f8b0e3bd1d77b2f4f2354e7a49a8
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Mon Jun 22 15:47:40 2015 +0200
Make /nix/var/nix/db/reserved bigger
Issue #564.
commit 60bda60fc06135aa97a93301b1a9e2270768f5b3
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Wed Jun 10 16:17:06 2015 +0200
Export outputPaths function
This is useful for the new hydra-queue-runner.
commit 5dfea34048aa8541f20aeb2fbcd163561b609a49
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Thu Jul 2 22:51:33 2015 +0200
Use std::vector::data()
commit 2459458bc8257734ca78cb7a2db3df20bd730ec0
Author: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Thu Jun 4 16:04:41 2015 +0200
Allow substitutes for builds that have preferLocalBuild set
Not substituting builds with "preferLocalBuild = true" was a bad idea,
because it didn't take the cost of dependencies into account. For
instance, if we can't substitute a fetchgit call, then we have to
download/build git and all its dependencies.
Partially reverts 5558652709f27e8a887580b77b93c705659d7a4b and adds a
new derivation attribute "allowSubstitutes" to specify whether a
derivation may be substituted.
| -rw-r--r-- | nix/libstore/build.cc | 62 | ||||
| -rw-r--r-- | nix/libstore/derivations.cc | 9 | ||||
| -rw-r--r-- | nix/libstore/derivations.hh | 1 | ||||
| -rw-r--r-- | nix/libstore/gc.cc | 31 | ||||
| -rw-r--r-- | nix/libstore/globals.cc | 2 | ||||
| -rw-r--r-- | nix/libstore/local-store.cc | 18 | ||||
| -rw-r--r-- | nix/libstore/misc.cc | 4 | ||||
| -rw-r--r-- | nix/libstore/misc.hh | 2 | ||||
| -rw-r--r-- | nix/libutil/util.cc | 11 | ||||
| -rw-r--r-- | nix/libutil/util.hh | 2 | ||||
| -rw-r--r-- | nix/nix-daemon/nix-daemon.cc | 5 |
11 files changed, 93 insertions, 54 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 85a818ba94f..a9eedcef167 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc | |||
| @@ -447,6 +447,7 @@ private: | |||
| 447 | string user; | 447 | string user; |
| 448 | uid_t uid; | 448 | uid_t uid; |
| 449 | gid_t gid; | 449 | gid_t gid; |
| 450 | std::vector<gid_t> supplementaryGIDs; | ||
| 450 | 451 | ||
| 451 | public: | 452 | public: |
| 452 | UserLock(); | 453 | UserLock(); |
| @@ -460,6 +461,7 @@ public: | |||
| 460 | string getUser() { return user; } | 461 | string getUser() { return user; } |
| 461 | uid_t getUID() { return uid; } | 462 | uid_t getUID() { return uid; } |
| 462 | uid_t getGID() { return gid; } | 463 | uid_t getGID() { return gid; } |
| 464 | std::vector<gid_t> getSupplementaryGIDs() { return supplementaryGIDs; } | ||
| 463 | 465 | ||
| 464 | bool enabled() { return uid != 0; } | 466 | bool enabled() { return uid != 0; } |
| 465 | 467 | ||
| @@ -539,6 +541,17 @@ void UserLock::acquire() | |||
| 539 | throw Error(format("the Nix user should not be a member of `%1%'") | 541 | throw Error(format("the Nix user should not be a member of `%1%'") |
| 540 | % settings.buildUsersGroup); | 542 | % settings.buildUsersGroup); |
| 541 | 543 | ||
| 544 | /* Get the list of supplementary groups of this build user. This | ||
| 545 | is usually either empty or contains a group such as "kvm". */ | ||
| 546 | supplementaryGIDs.resize(10); | ||
| 547 | int ngroups = supplementaryGIDs.size(); | ||
| 548 | int err = getgrouplist(pw->pw_name, pw->pw_gid, | ||
| 549 | supplementaryGIDs.data(), &ngroups); | ||
| 550 | if (err == -1) | ||
| 551 | throw Error(format("failed to get list of supplementary groups for ‘%1%’") % pw->pw_name); | ||
| 552 | |||
| 553 | supplementaryGIDs.resize(ngroups); | ||
| 554 | |||
| 542 | return; | 555 | return; |
| 543 | } | 556 | } |
| 544 | } | 557 | } |
| @@ -1000,7 +1013,7 @@ void DerivationGoal::haveDerivation() | |||
| 1000 | /* We are first going to try to create the invalid output paths | 1013 | /* We are first going to try to create the invalid output paths |
| 1001 | through substitutes. If that doesn't work, we'll build | 1014 | through substitutes. If that doesn't work, we'll build |
| 1002 | them. */ | 1015 | them. */ |
| 1003 | if (settings.useSubstitutes && !willBuildLocally(drv)) | 1016 | if (settings.useSubstitutes && substitutesAllowed(drv)) |
| 1004 | foreach (PathSet::iterator, i, invalidOutputs) | 1017 | foreach (PathSet::iterator, i, invalidOutputs) |
| 1005 | addWaitee(worker.makeSubstitutionGoal(*i, buildMode == bmRepair)); | 1018 | addWaitee(worker.makeSubstitutionGoal(*i, buildMode == bmRepair)); |
| 1006 | 1019 | ||
| @@ -1188,35 +1201,32 @@ void DerivationGoal::inputsRealised() | |||
| 1188 | } | 1201 | } |
| 1189 | 1202 | ||
| 1190 | 1203 | ||
| 1191 | PathSet outputPaths(const DerivationOutputs & outputs) | 1204 | static bool canBuildLocally(const string & platform) |
| 1192 | { | 1205 | { |
| 1193 | PathSet paths; | 1206 | return platform == settings.thisSystem |
| 1194 | foreach (DerivationOutputs::const_iterator, i, outputs) | 1207 | #if __linux__ |
| 1195 | paths.insert(i->second.path); | 1208 | || (platform == "i686-linux" && settings.thisSystem == "x86_64-linux") |
| 1196 | return paths; | 1209 | #endif |
| 1210 | ; | ||
| 1197 | } | 1211 | } |
| 1198 | 1212 | ||
| 1199 | 1213 | ||
| 1200 | static string get(const StringPairs & map, const string & key) | 1214 | static string get(const StringPairs & map, const string & key, const string & def = "") |
| 1201 | { | 1215 | { |
| 1202 | StringPairs::const_iterator i = map.find(key); | 1216 | StringPairs::const_iterator i = map.find(key); |
| 1203 | return i == map.end() ? (string) "" : i->second; | 1217 | return i == map.end() ? def : i->second; |
| 1204 | } | 1218 | } |
| 1205 | 1219 | ||
| 1206 | 1220 | ||
| 1207 | static bool canBuildLocally(const string & platform) | 1221 | bool willBuildLocally(const Derivation & drv) |
| 1208 | { | 1222 | { |
| 1209 | return platform == settings.thisSystem | 1223 | return get(drv.env, "preferLocalBuild") == "1" && canBuildLocally(drv.platform); |
| 1210 | #if __linux__ | ||
| 1211 | || (platform == "i686-linux" && settings.thisSystem == "x86_64-linux") | ||
| 1212 | #endif | ||
| 1213 | ; | ||
| 1214 | } | 1224 | } |
| 1215 | 1225 | ||
| 1216 | 1226 | ||
| 1217 | bool willBuildLocally(const Derivation & drv) | 1227 | bool substitutesAllowed(const Derivation & drv) |
| 1218 | { | 1228 | { |
| 1219 | return get(drv.env, "preferLocalBuild") == "1" && canBuildLocally(drv.platform); | 1229 | return get(drv.env, "allowSubstitutes", "1") == "1"; |
| 1220 | } | 1230 | } |
| 1221 | 1231 | ||
| 1222 | 1232 | ||
| @@ -1242,7 +1252,7 @@ void DerivationGoal::tryToBuild() | |||
| 1242 | can't acquire the lock, then continue; hopefully some other | 1252 | can't acquire the lock, then continue; hopefully some other |
| 1243 | goal can start a build, and if not, the main loop will sleep a | 1253 | goal can start a build, and if not, the main loop will sleep a |
| 1244 | few seconds and then retry this goal. */ | 1254 | few seconds and then retry this goal. */ |
| 1245 | if (!outputLocks.lockPaths(outputPaths(drv.outputs), "", false)) { | 1255 | if (!outputLocks.lockPaths(outputPaths(drv), "", false)) { |
| 1246 | worker.waitForAWhile(shared_from_this()); | 1256 | worker.waitForAWhile(shared_from_this()); |
| 1247 | return; | 1257 | return; |
| 1248 | } | 1258 | } |
| @@ -1263,7 +1273,7 @@ void DerivationGoal::tryToBuild() | |||
| 1263 | return; | 1273 | return; |
| 1264 | } | 1274 | } |
| 1265 | 1275 | ||
| 1266 | missingPaths = outputPaths(drv.outputs); | 1276 | missingPaths = outputPaths(drv); |
| 1267 | if (buildMode != bmCheck) | 1277 | if (buildMode != bmCheck) |
| 1268 | foreach (PathSet::iterator, i, validPaths) missingPaths.erase(*i); | 1278 | foreach (PathSet::iterator, i, validPaths) missingPaths.erase(*i); |
| 1269 | 1279 | ||
| @@ -2168,7 +2178,6 @@ void DerivationGoal::runChild() | |||
| 2168 | Strings envStrs; | 2178 | Strings envStrs; |
| 2169 | foreach (Environment::const_iterator, i, env) | 2179 | foreach (Environment::const_iterator, i, env) |
| 2170 | envStrs.push_back(rewriteHashes(i->first + "=" + i->second, rewritesToTmp)); | 2180 | envStrs.push_back(rewriteHashes(i->first + "=" + i->second, rewritesToTmp)); |
| 2171 | auto envArr = stringsToCharPtrs(envStrs); | ||
| 2172 | 2181 | ||
| 2173 | /* If we are running in `build-users' mode, then switch to the | 2182 | /* If we are running in `build-users' mode, then switch to the |
| 2174 | user we allocated above. Make sure that we drop all root | 2183 | user we allocated above. Make sure that we drop all root |
| @@ -2177,10 +2186,11 @@ void DerivationGoal::runChild() | |||
| 2177 | setuid() when run as root sets the real, effective and | 2186 | setuid() when run as root sets the real, effective and |
| 2178 | saved UIDs. */ | 2187 | saved UIDs. */ |
| 2179 | if (buildUser.enabled()) { | 2188 | if (buildUser.enabled()) { |
| 2180 | printMsg(lvlChatty, format("switching to user `%1%'") % buildUser.getUser()); | 2189 | /* Preserve supplementary groups of the build user, to allow |
| 2181 | 2190 | admins to specify groups such as "kvm". */ | |
| 2182 | if (setgroups(0, 0) == -1) | 2191 | if (setgroups(buildUser.getSupplementaryGIDs().size(), |
| 2183 | throw SysError("cannot clear the set of supplementary groups"); | 2192 | buildUser.getSupplementaryGIDs().data()) == -1) |
| 2193 | throw SysError("cannot set supplementary groups of build user"); | ||
| 2184 | 2194 | ||
| 2185 | if (setgid(buildUser.getGID()) == -1 || | 2195 | if (setgid(buildUser.getGID()) == -1 || |
| 2186 | getgid() != buildUser.getGID() || | 2196 | getgid() != buildUser.getGID() || |
| @@ -2199,7 +2209,6 @@ void DerivationGoal::runChild() | |||
| 2199 | args.push_back(builderBasename); | 2209 | args.push_back(builderBasename); |
| 2200 | foreach (Strings::iterator, i, drv.args) | 2210 | foreach (Strings::iterator, i, drv.args) |
| 2201 | args.push_back(rewriteHashes(*i, rewritesToTmp)); | 2211 | args.push_back(rewriteHashes(*i, rewritesToTmp)); |
| 2202 | auto argArr = stringsToCharPtrs(args); | ||
| 2203 | 2212 | ||
| 2204 | restoreSIGPIPE(); | 2213 | restoreSIGPIPE(); |
| 2205 | 2214 | ||
| @@ -2207,7 +2216,7 @@ void DerivationGoal::runChild() | |||
| 2207 | writeFull(STDERR_FILENO, "\n"); | 2216 | writeFull(STDERR_FILENO, "\n"); |
| 2208 | 2217 | ||
| 2209 | /* Execute the program. This should not return. */ | 2218 | /* Execute the program. This should not return. */ |
| 2210 | execve(drv.builder.c_str(), (char * *) &argArr[0], (char * *) &envArr[0]); | 2219 | execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data()); |
| 2211 | 2220 | ||
| 2212 | throw SysError(format("executing `%1%'") % drv.builder); | 2221 | throw SysError(format("executing `%1%'") % drv.builder); |
| 2213 | 2222 | ||
| @@ -2837,7 +2846,6 @@ void SubstitutionGoal::tryToRun() | |||
| 2837 | args.push_back("--substitute"); | 2846 | args.push_back("--substitute"); |
| 2838 | args.push_back(storePath); | 2847 | args.push_back(storePath); |
| 2839 | args.push_back(destPath); | 2848 | args.push_back(destPath); |
| 2840 | auto argArr = stringsToCharPtrs(args); | ||
| 2841 | 2849 | ||
| 2842 | /* Fork the substitute program. */ | 2850 | /* Fork the substitute program. */ |
| 2843 | pid = startProcess([&]() { | 2851 | pid = startProcess([&]() { |
| @@ -2847,7 +2855,7 @@ void SubstitutionGoal::tryToRun() | |||
| 2847 | if (dup2(outPipe.writeSide, STDOUT_FILENO) == -1) | 2855 | if (dup2(outPipe.writeSide, STDOUT_FILENO) == -1) |
| 2848 | throw SysError("cannot dup output pipe into stdout"); | 2856 | throw SysError("cannot dup output pipe into stdout"); |
| 2849 | 2857 | ||
| 2850 | execv(sub.c_str(), (char * *) &argArr[0]); | 2858 | execv(sub.c_str(), stringsToCharPtrs(args).data()); |
| 2851 | 2859 | ||
| 2852 | throw SysError(format("executing `%1%'") % sub); | 2860 | throw SysError(format("executing `%1%'") % sub); |
| 2853 | }); | 2861 | }); |
diff --git a/nix/libstore/derivations.cc b/nix/libstore/derivations.cc index b452aa2caf5..d316f6c7bf1 100644 --- a/nix/libstore/derivations.cc +++ b/nix/libstore/derivations.cc | |||
| @@ -285,4 +285,13 @@ bool wantOutput(const string & output, const std::set<string> & wanted) | |||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | 287 | ||
| 288 | PathSet outputPaths(const Derivation & drv) | ||
| 289 | { | ||
| 290 | PathSet paths; | ||
| 291 | for (auto & i : drv.outputs) | ||
| 292 | paths.insert(i.second.path); | ||
| 293 | return paths; | ||
| 294 | } | ||
| 295 | |||
| 296 | |||
| 288 | } | 297 | } |
diff --git a/nix/libstore/derivations.hh b/nix/libstore/derivations.hh index 04b64dfc88a..8d5e4d05d46 100644 --- a/nix/libstore/derivations.hh +++ b/nix/libstore/derivations.hh | |||
| @@ -89,5 +89,6 @@ Path makeDrvPathWithOutputs(const Path & drvPath, const std::set<string> & outpu | |||
| 89 | 89 | ||
| 90 | bool wantOutput(const string & output, const std::set<string> & wanted); | 90 | bool wantOutput(const string & output, const std::set<string> & wanted); |
| 91 | 91 | ||
| 92 | PathSet outputPaths(const Derivation & drv); | ||
| 92 | 93 | ||
| 93 | } | 94 | } |
diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc index 34768324c26..72eff524265 100644 --- a/nix/libstore/gc.cc +++ b/nix/libstore/gc.cc | |||
| @@ -376,6 +376,7 @@ struct LocalStore::GCState | |||
| 376 | bool gcKeepOutputs; | 376 | bool gcKeepOutputs; |
| 377 | bool gcKeepDerivations; | 377 | bool gcKeepDerivations; |
| 378 | unsigned long long bytesInvalidated; | 378 | unsigned long long bytesInvalidated; |
| 379 | bool moveToTrash = true; | ||
| 379 | Path trashDir; | 380 | Path trashDir; |
| 380 | bool shouldDelete; | 381 | bool shouldDelete; |
| 381 | GCState(GCResults & results_) : results(results_), bytesInvalidated(0) { } | 382 | GCState(GCResults & results_) : results(results_), bytesInvalidated(0) { } |
| @@ -428,16 +429,23 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path) | |||
| 428 | not holding the global GC lock) we can delete the path without | 429 | not holding the global GC lock) we can delete the path without |
| 429 | being afraid that the path has become alive again. Otherwise | 430 | being afraid that the path has become alive again. Otherwise |
| 430 | delete it right away. */ | 431 | delete it right away. */ |
| 431 | if (S_ISDIR(st.st_mode)) { | 432 | if (state.moveToTrash && S_ISDIR(st.st_mode)) { |
| 432 | // Estimate the amount freed using the narSize field. FIXME: | 433 | // Estimate the amount freed using the narSize field. FIXME: |
| 433 | // if the path was not valid, need to determine the actual | 434 | // if the path was not valid, need to determine the actual |
| 434 | // size. | 435 | // size. |
| 435 | state.bytesInvalidated += size; | 436 | try { |
| 436 | if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) | 437 | if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) |
| 437 | throw SysError(format("making `%1%' writable") % path); | 438 | throw SysError(format("making `%1%' writable") % path); |
| 438 | Path tmp = state.trashDir + "/" + baseNameOf(path); | 439 | Path tmp = state.trashDir + "/" + baseNameOf(path); |
| 439 | if (rename(path.c_str(), tmp.c_str())) | 440 | if (rename(path.c_str(), tmp.c_str())) |
| 440 | throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp); | 441 | throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp); |
| 442 | state.bytesInvalidated += size; | ||
| 443 | } catch (SysError & e) { | ||
| 444 | if (e.errNo == ENOSPC) { | ||
| 445 | printMsg(lvlInfo, format("note: can't create move `%1%': %2%") % path % e.msg()); | ||
| 446 | deleteGarbage(state, path); | ||
| 447 | } | ||
| 448 | } | ||
| 441 | } else | 449 | } else |
| 442 | deleteGarbage(state, path); | 450 | deleteGarbage(state, path); |
| 443 | 451 | ||
| @@ -636,7 +644,14 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) | |||
| 636 | 644 | ||
| 637 | if (state.shouldDelete) { | 645 | if (state.shouldDelete) { |
| 638 | if (pathExists(state.trashDir)) deleteGarbage(state, state.trashDir); | 646 | if (pathExists(state.trashDir)) deleteGarbage(state, state.trashDir); |
| 639 | createDirs(state.trashDir); | 647 | try { |
| 648 | createDirs(state.trashDir); | ||
| 649 | } catch (SysError & e) { | ||
| 650 | if (e.errNo == ENOSPC) { | ||
| 651 | printMsg(lvlInfo, format("note: can't create trash directory: %1%") % e.msg()); | ||
| 652 | state.moveToTrash = false; | ||
| 653 | } | ||
| 654 | } | ||
| 640 | } | 655 | } |
| 641 | 656 | ||
| 642 | /* Now either delete all garbage paths, or just the specified | 657 | /* Now either delete all garbage paths, or just the specified |
diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc index bb08a7d0b08..07f23d469c0 100644 --- a/nix/libstore/globals.cc +++ b/nix/libstore/globals.cc | |||
| @@ -36,7 +36,7 @@ Settings::Settings() | |||
| 36 | buildTimeout = 0; | 36 | buildTimeout = 0; |
| 37 | useBuildHook = true; | 37 | useBuildHook = true; |
| 38 | printBuildTrace = false; | 38 | printBuildTrace = false; |
| 39 | reservedSize = 1024 * 1024; | 39 | reservedSize = 8 * 1024 * 1024; |
| 40 | fsyncMetadata = true; | 40 | fsyncMetadata = true; |
| 41 | useSQLiteWAL = true; | 41 | useSQLiteWAL = true; |
| 42 | syncBeforeRegistering = false; | 42 | syncBeforeRegistering = false; |
diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index 630cb80c413..b2c78477b62 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc | |||
| @@ -288,7 +288,17 @@ LocalStore::LocalStore(bool reserveSpace) | |||
| 288 | struct stat st; | 288 | struct stat st; |
| 289 | if (stat(reservedPath.c_str(), &st) == -1 || | 289 | if (stat(reservedPath.c_str(), &st) == -1 || |
| 290 | st.st_size != settings.reservedSize) | 290 | st.st_size != settings.reservedSize) |
| 291 | writeFile(reservedPath, string(settings.reservedSize, 'X')); | 291 | { |
| 292 | AutoCloseFD fd = open(reservedPath.c_str(), O_WRONLY | O_CREAT, 0600); | ||
| 293 | int res = -1; | ||
| 294 | #if HAVE_POSIX_FALLOCATE | ||
| 295 | res = posix_fallocate(fd, 0, settings.reservedSize); | ||
| 296 | #endif | ||
| 297 | if (res == -1) { | ||
| 298 | writeFull(fd, string(settings.reservedSize, 'X')); | ||
| 299 | ftruncate(fd, settings.reservedSize); | ||
| 300 | } | ||
| 301 | } | ||
| 292 | } | 302 | } |
| 293 | else | 303 | else |
| 294 | deletePath(reservedPath); | 304 | deletePath(reservedPath); |
| @@ -1166,10 +1176,8 @@ string LocalStore::getLineFromSubstituter(RunningSubstituter & run) | |||
| 1166 | if (n == 0) throw EndOfFile(format("substituter `%1%' died unexpectedly") % run.program); | 1176 | if (n == 0) throw EndOfFile(format("substituter `%1%' died unexpectedly") % run.program); |
| 1167 | err.append(buf, n); | 1177 | err.append(buf, n); |
| 1168 | string::size_type p; | 1178 | string::size_type p; |
| 1169 | while (((p = err.find('\n')) != string::npos) | 1179 | while ((p = err.find('\n')) != string::npos) { |
| 1170 | || ((p = err.find('\r')) != string::npos)) { | 1180 | printMsg(lvlError, run.program + ": " + string(err, 0, p)); |
| 1171 | string thing(err, 0, p + 1); | ||
| 1172 | writeToStderr(run.program + ": " + thing); | ||
| 1173 | err = string(err, p + 1); | 1181 | err = string(err, p + 1); |
| 1174 | } | 1182 | } |
| 1175 | } | 1183 | } |
diff --git a/nix/libstore/misc.cc b/nix/libstore/misc.cc index 6ecf8787cf6..22363af1264 100644 --- a/nix/libstore/misc.cc +++ b/nix/libstore/misc.cc | |||
| @@ -120,7 +120,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets, | |||
| 120 | if (invalid.empty()) continue; | 120 | if (invalid.empty()) continue; |
| 121 | 121 | ||
| 122 | todoDrv.insert(*i); | 122 | todoDrv.insert(*i); |
| 123 | if (settings.useSubstitutes && !willBuildLocally(drv)) | 123 | if (settings.useSubstitutes && substitutesAllowed(drv)) |
| 124 | query.insert(invalid.begin(), invalid.end()); | 124 | query.insert(invalid.begin(), invalid.end()); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| @@ -144,7 +144,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets, | |||
| 144 | 144 | ||
| 145 | PathSet outputs; | 145 | PathSet outputs; |
| 146 | bool mustBuild = false; | 146 | bool mustBuild = false; |
| 147 | if (settings.useSubstitutes && !willBuildLocally(drv)) { | 147 | if (settings.useSubstitutes && substitutesAllowed(drv)) { |
| 148 | foreach (DerivationOutputs::iterator, j, drv.outputs) { | 148 | foreach (DerivationOutputs::iterator, j, drv.outputs) { |
| 149 | if (!wantOutput(j->first, i2.second)) continue; | 149 | if (!wantOutput(j->first, i2.second)) continue; |
| 150 | if (!store.isValidPath(j->second.path)) { | 150 | if (!store.isValidPath(j->second.path)) { |
diff --git a/nix/libstore/misc.hh b/nix/libstore/misc.hh index 144cb7f457c..d3e31d51f72 100644 --- a/nix/libstore/misc.hh +++ b/nix/libstore/misc.hh | |||
| @@ -34,5 +34,7 @@ void queryMissing(StoreAPI & store, const PathSet & targets, | |||
| 34 | 34 | ||
| 35 | bool willBuildLocally(const Derivation & drv); | 35 | bool willBuildLocally(const Derivation & drv); |
| 36 | 36 | ||
| 37 | bool substitutesAllowed(const Derivation & drv); | ||
| 38 | |||
| 37 | 39 | ||
| 38 | } | 40 | } |
diff --git a/nix/libutil/util.cc b/nix/libutil/util.cc index dab4235b04f..14026ab8295 100644 --- a/nix/libutil/util.cc +++ b/nix/libutil/util.cc | |||
| @@ -897,10 +897,10 @@ pid_t startProcess(std::function<void()> fun, | |||
| 897 | } | 897 | } |
| 898 | 898 | ||
| 899 | 899 | ||
| 900 | std::vector<const char *> stringsToCharPtrs(const Strings & ss) | 900 | std::vector<char *> stringsToCharPtrs(const Strings & ss) |
| 901 | { | 901 | { |
| 902 | std::vector<const char *> res; | 902 | std::vector<char *> res; |
| 903 | for (auto & s : ss) res.push_back(s.c_str()); | 903 | for (auto & s : ss) res.push_back((char *) s.c_str()); |
| 904 | res.push_back(0); | 904 | res.push_back(0); |
| 905 | return res; | 905 | return res; |
| 906 | } | 906 | } |
| @@ -921,12 +921,11 @@ string runProgram(Path program, bool searchPath, const Strings & args) | |||
| 921 | 921 | ||
| 922 | Strings args_(args); | 922 | Strings args_(args); |
| 923 | args_.push_front(program); | 923 | args_.push_front(program); |
| 924 | auto cargs = stringsToCharPtrs(args_); | ||
| 925 | 924 | ||
| 926 | if (searchPath) | 925 | if (searchPath) |
| 927 | execvp(program.c_str(), (char * *) &cargs[0]); | 926 | execvp(program.c_str(), stringsToCharPtrs(args_).data()); |
| 928 | else | 927 | else |
| 929 | execv(program.c_str(), (char * *) &cargs[0]); | 928 | execv(program.c_str(), stringsToCharPtrs(args_).data()); |
| 930 | 929 | ||
| 931 | throw SysError(format("executing `%1%'") % program); | 930 | throw SysError(format("executing `%1%'") % program); |
| 932 | }); | 931 | }); |
diff --git a/nix/libutil/util.hh b/nix/libutil/util.hh index 6a84ed88518..24e16ba36a0 100644 --- a/nix/libutil/util.hh +++ b/nix/libutil/util.hh | |||
| @@ -284,7 +284,7 @@ MakeError(ExecError, Error) | |||
| 284 | /* Convert a list of strings to a null-terminated vector of char | 284 | /* Convert a list of strings to a null-terminated vector of char |
| 285 | *'s. The result must not be accessed beyond the lifetime of the | 285 | *'s. The result must not be accessed beyond the lifetime of the |
| 286 | list of strings. */ | 286 | list of strings. */ |
| 287 | std::vector<const char *> stringsToCharPtrs(const Strings & ss); | 287 | std::vector<char *> stringsToCharPtrs(const Strings & ss); |
| 288 | 288 | ||
| 289 | /* Close all file descriptors except stdin, stdout, stderr, and those | 289 | /* Close all file descriptors except stdin, stdout, stderr, and those |
| 290 | listed in the given set. Good practice in child processes. */ | 290 | listed in the given set. Good practice in child processes. */ |
diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc index 10159db62e0..2b89190dbe0 100644 --- a/nix/nix-daemon/nix-daemon.cc +++ b/nix/nix-daemon/nix-daemon.cc | |||
| @@ -440,10 +440,7 @@ static void performOp(bool trusted, unsigned int clientVersion, | |||
| 440 | case wopImportPaths: { | 440 | case wopImportPaths: { |
| 441 | startWork(); | 441 | startWork(); |
| 442 | TunnelSource source(from); | 442 | TunnelSource source(from); |
| 443 | 443 | Paths paths = store->importPaths(!trusted, source); | |
| 444 | /* Unlike Nix, always require a signature, even for "trusted" | ||
| 445 | users. */ | ||
| 446 | Paths paths = store->importPaths(true, source); | ||
| 447 | stopWork(); | 444 | stopWork(); |
| 448 | writeStrings(paths, to); | 445 | writeStrings(paths, to); |
| 449 | break; | 446 | break; |
