aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorAlexander Bantyev <balsoft@balsoft.ru>2020-05-08 12:22:39 +0300
committerAlexander Bantyev <balsoft@balsoft.ru>2020-05-08 12:22:39 +0300
commit14073fb76be0f46cb9335edf747fcfa1a5275b7b (patch)
treee4762aa892bfacac83ed2cebef315b2263f1a35e /src/libstore
parent04967dee9d08befe4661e6fa5da4a00da0538a13 (diff)
Don't block while waiting for build users
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc54
1 files changed, 29 insertions, 25 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 1b7e6d75e..00101f553 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -507,9 +507,6 @@ private:
Path fnUserLock;
AutoCloseFD fdUserLock;
- bool findFreeUser();
-
-
string user;
uid_t uid;
gid_t gid;
@@ -525,20 +522,19 @@ public:
uid_t getGID() { assert(gid); return gid; }
std::vector<gid_t> getSupplementaryGIDs() { return supplementaryGIDs; }
+ bool findFreeUser();
+
bool enabled() { return uid != 0; }
};
+
UserLock::UserLock()
{
assert(settings.buildUsersGroup != "");
createDirs(settings.nixStateDir + "/userpool");
-
- if (findFreeUser()) return;
-
- printError("waiting for build users");
-
- do std::this_thread::sleep_for(std::chrono::seconds(2)); while (! findFreeUser());
+ /* Mark that user is not enabled by default */
+ uid = 0;
}
bool UserLock::findFreeUser() {
@@ -1398,6 +1394,30 @@ void DerivationGoal::tryToBuild()
{
trace("trying to build");
+ /* If `build-users-group' is not empty, then we have to build as
+ one of the members of that group. */
+ if (settings.buildUsersGroup != "" && getuid() == 0) {
+#if defined(__linux__) || defined(__APPLE__)
+ if (!buildUser) buildUser = std::make_unique<UserLock>();
+
+ if (!buildUser->enabled()) {
+ if (!buildUser->findFreeUser()) {
+ debug("waiting for build users");
+ worker.waitForAWhile(shared_from_this());
+ return;
+ }
+
+ /* Make sure that no other processes are executing under this
+ uid. */
+ buildUser->kill();
+ }
+#else
+ /* Don't know how to block the creation of setuid/setgid
+ binaries on this platform. */
+ throw Error("build users are not supported on this platform for security reasons");
+#endif
+ }
+
/* Obtain locks on all output paths. The locks are automatically
released when we exit this function or Nix crashes. If we
can't acquire the lock, then continue; hopefully some other
@@ -1950,22 +1970,6 @@ void DerivationGoal::startBuilder()
#endif
}
- /* If `build-users-group' is not empty, then we have to build as
- one of the members of that group. */
- if (settings.buildUsersGroup != "" && getuid() == 0) {
-#if defined(__linux__) || defined(__APPLE__)
- buildUser = std::make_unique<UserLock>();
-
- /* Make sure that no other processes are executing under this
- uid. */
- buildUser->kill();
-#else
- /* Don't know how to block the creation of setuid/setgid
- binaries on this platform. */
- throw Error("build users are not supported on this platform for security reasons");
-#endif
- }
-
/* Create a temporary directory where the build will take
place. */
tmpDir = createTempDir("", "nix-build-" + std::string(drvPath.name()), false, false, 0700);