summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-07-02 23:37:29 +0200
committerLudovic Courtès <ludo@gnu.org>2015-07-03 00:30:55 +0200
commit322eeb87d0e5bb608ae1c176611a50297c93cbe8 (patch)
treeecc0c32c8365b66021be9a26b77a084efc179be3
parentd2cef629fd5856540f6e1edf8f9d2131ec7a6942 (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.cc62
-rw-r--r--nix/libstore/derivations.cc9
-rw-r--r--nix/libstore/derivations.hh1
-rw-r--r--nix/libstore/gc.cc31
-rw-r--r--nix/libstore/globals.cc2
-rw-r--r--nix/libstore/local-store.cc18
-rw-r--r--nix/libstore/misc.cc4
-rw-r--r--nix/libstore/misc.hh2
-rw-r--r--nix/libutil/util.cc11
-rw-r--r--nix/libutil/util.hh2
-rw-r--r--nix/nix-daemon/nix-daemon.cc5
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
451public: 452public:
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
1191PathSet outputPaths(const DerivationOutputs & outputs) 1204static 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
1200static string get(const StringPairs & map, const string & key) 1214static 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
1207static bool canBuildLocally(const string & platform) 1221bool 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
1217bool willBuildLocally(const Derivation & drv) 1227bool 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
288PathSet 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
90bool wantOutput(const string & output, const std::set<string> & wanted); 90bool wantOutput(const string & output, const std::set<string> & wanted);
91 91
92PathSet 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
35bool willBuildLocally(const Derivation & drv); 35bool willBuildLocally(const Derivation & drv);
36 36
37bool 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
900std::vector<const char *> stringsToCharPtrs(const Strings & ss) 900std::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. */
287std::vector<const char *> stringsToCharPtrs(const Strings & ss); 287std::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;