about summary refs log tree commit diff
path: root/src/nix-worker
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix-worker')
-rw-r--r--src/nix-worker/nix-worker.cc158
1 files changed, 98 insertions, 60 deletions
diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc
index 7099eb9eeb0d..dadde9cc5183 100644
--- a/src/nix-worker/nix-worker.cc
+++ b/src/nix-worker/nix-worker.cc
@@ -95,7 +95,7 @@ static bool isFarSideClosed(int socket)
         throw Error("EOF expected (protocol error?)");
     else if (rd == -1 && errno != ECONNRESET)
         throw SysError("expected connection reset or EOF");
-    
+
     return true;
 }
 
@@ -185,7 +185,7 @@ static void stopWork(bool success = true, const string & msg = "", unsigned int
        we're either sending or receiving from the client, so we'll be
        notified of client death anyway. */
     setSigPollAction(false);
-    
+
     canSendStderr = false;
 
     if (success)
@@ -220,7 +220,7 @@ struct TunnelSource : BufferedSource
            so we have to disable the SIGPOLL handler. */
         setSigPollAction(false);
         canSendStderr = false;
-        
+
         writeInt(STDERR_READ, to);
         writeInt(len, to);
         to.flush();
@@ -279,7 +279,7 @@ static void performOp(unsigned int clientVersion,
 {
     switch (op) {
 
-#if 0        
+#if 0
     case wopQuit: {
         /* Close the database. */
         store.reset((StoreAPI *) 0);
@@ -297,12 +297,30 @@ static void performOp(unsigned int clientVersion,
         break;
     }
 
+    case wopQueryValidPaths: {
+        PathSet paths = readStorePaths<PathSet>(from);
+        startWork();
+        PathSet res = store->queryValidPaths(paths);
+        stopWork();
+        writeStrings(res, to);
+        break;
+    }
+
     case wopHasSubstitutes: {
         Path path = readStorePath(from);
         startWork();
-        bool result = store->hasSubstitutes(path);
+        PathSet res = store->querySubstitutablePaths(singleton<PathSet>(path));
         stopWork();
-        writeInt(result, to);
+        writeInt(res.find(path) != res.end(), to);
+        break;
+    }
+
+    case wopQuerySubstitutablePaths: {
+        PathSet paths = readStorePaths<PathSet>(from);
+        startWork();
+        PathSet res = store->querySubstitutablePaths(paths);
+        stopWork();
+        writeStrings(res, to);
         break;
     }
 
@@ -373,7 +391,7 @@ static void performOp(unsigned int clientVersion,
 
         SavingSourceAdapter savedNAR(from);
         RetrieveRegularNARSink savedRegular;
-        
+
         if (recursive) {
             /* Get the entire NAR dump from the client and save it to
                a string so that we can pass it to
@@ -382,13 +400,13 @@ static void performOp(unsigned int clientVersion,
             parseDump(sink, savedNAR);
         } else
             parseDump(savedRegular, from);
-            
+
         startWork();
         if (!savedRegular.regular) throw Error("regular file expected");
         Path path = dynamic_cast<LocalStore *>(store.get())
             ->addToStoreFromDump(recursive ? savedNAR.s : savedRegular.s, baseName, recursive, hashAlgo);
         stopWork();
-        
+
         writeString(path, to);
         break;
     }
@@ -494,41 +512,45 @@ static void performOp(unsigned int clientVersion,
         }
 
         GCResults results;
-        
+
         startWork();
         if (options.ignoreLiveness)
             throw Error("you are not allowed to ignore liveness");
         store->collectGarbage(options, results);
         stopWork();
-        
+
         writeStrings(results.paths, to);
         writeLongLong(results.bytesFreed, to);
         writeLongLong(0, to); // obsolete
-        
+
         break;
     }
 
     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;
+        if (GET_PROTOCOL_MINOR(clientVersion) >= 12) {
+            unsigned int n = readInt(from);
+            for (unsigned int i = 0; i < n; i++) {
+                string name = readString(from);
+                string value = readString(from);
+                settings.set("untrusted-" + name, value);
+            }
         }
         startWork();
         stopWork();
@@ -538,23 +560,43 @@ static void performOp(unsigned int clientVersion,
     case wopQuerySubstitutablePathInfo: {
         Path path = absPath(readString(from));
         startWork();
-        SubstitutablePathInfo info;
-        bool res = store->querySubstitutablePathInfo(path, info);
+        SubstitutablePathInfos infos;
+        store->querySubstitutablePathInfos(singleton<PathSet>(path), infos);
         stopWork();
-        writeInt(res ? 1 : 0, to);
-        if (res) {
-            writeString(info.deriver, to);
-            writeStrings(info.references, to);
-            writeLongLong(info.downloadSize, to);
+        SubstitutablePathInfos::iterator i = infos.find(path);
+        if (i == infos.end())
+            writeInt(0, to);
+        else {
+            writeInt(1, to);
+            writeString(i->second.deriver, to);
+            writeStrings(i->second.references, to);
+            writeLongLong(i->second.downloadSize, to);
             if (GET_PROTOCOL_MINOR(clientVersion) >= 7)
-                writeLongLong(info.narSize, to);
+                writeLongLong(i->second.narSize, to);
         }
         break;
     }
-            
-    case wopQueryValidPaths: {
+
+    case wopQuerySubstitutablePathInfos: {
+        PathSet paths = readStorePaths<PathSet>(from);
         startWork();
-        PathSet paths = store->queryValidPaths();
+        SubstitutablePathInfos infos;
+        store->querySubstitutablePathInfos(paths, infos);
+        stopWork();
+        writeInt(infos.size(), to);
+        foreach (SubstitutablePathInfos::iterator, i, infos) {
+            writeString(i->first, to);
+            writeString(i->second.deriver, to);
+            writeStrings(i->second.references, to);
+            writeLongLong(i->second.downloadSize, to);
+            writeLongLong(i->second.narSize, to);
+        }
+        break;
+    }
+
+    case wopQueryAllValidPaths: {
+        startWork();
+        PathSet paths = store->queryAllValidPaths();
         stopWork();
         writeStrings(paths, to);
         break;
@@ -599,7 +641,7 @@ static void performOp(unsigned int clientVersion,
 static void processConnection()
 {
     canSendStderr = false;
-    myPid = getpid();    
+    myPid = getpid();
     writeToStderr = tunnelStderr;
 
 #ifdef HAVE_HUP_NOTIFICATION
@@ -643,7 +685,7 @@ static void processConnection()
 
         stopWork();
         to.flush();
-        
+
     } catch (Error & e) {
         stopWork(false, e.msg());
         to.flush();
@@ -652,7 +694,7 @@ static void processConnection()
 
     /* Process client requests. */
     unsigned int opCount = 0;
-    
+
     while (true) {
         WorkerOp op;
         try {
@@ -724,13 +766,13 @@ static void daemonLoop()
 
     /* Otherwise, create and bind to a Unix domain socket. */
     else {
-    
+
         /* Create and bind to a Unix domain socket. */
         fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
         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));
 
@@ -739,7 +781,7 @@ static void daemonLoop()
            relative path name. */
         chdir(dirOf(socketPath).c_str());
         Path socketPathRel = "./" + baseNameOf(socketPath);
-    
+
         struct sockaddr_un addr;
         addr.sun_family = AF_UNIX;
         if (socketPathRel.size() >= sizeof(addr.sun_path))
@@ -764,7 +806,7 @@ static void daemonLoop()
     }
 
     closeOnExec(fdSocket);
-        
+
     /* Loop accepting connections. */
     while (1) {
 
@@ -772,7 +814,7 @@ static void daemonLoop()
             /* Important: the server process *cannot* open the SQLite
                database, because it doesn't like forks very much. */
             assert(!store);
-            
+
             /* Accept a connection. */
             struct sockaddr_un remoteAddr;
             socklen_t remoteAddrLen = sizeof(remoteAddr);
@@ -781,14 +823,14 @@ static void daemonLoop()
                 (struct sockaddr *) &remoteAddr, &remoteAddrLen);
             checkInterrupt();
             if (remote == -1) {
-		if (errno == EINTR)
-		    continue;
-		else
-		    throw SysError("accepting connection");
+                if (errno == EINTR)
+                    continue;
+                else
+                    throw SysError("accepting connection");
             }
 
             closeOnExec(remote);
-            
+
             /* Get the identity of the caller, if possible. */
             uid_t clientUid = -1;
             pid_t clientPid = -1;
@@ -803,13 +845,13 @@ static void daemonLoop()
 #endif
 
             printMsg(lvlInfo, format("accepted connection from pid %1%, uid %2%") % clientPid % clientUid);
-            
+
             /* Fork a child to handle the connection. */
             pid_t child;
             child = fork();
-    
+
             switch (child) {
-        
+
             case -1:
                 throw SysError("unable to fork");
 
@@ -828,16 +870,12 @@ static void daemonLoop()
                         string processName = int2String(clientPid);
                         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;
                     processConnection();
-                    
+
                 } catch (std::exception & e) {
                     std::cerr << format("child error: %1%\n") % e.what();
                 }
@@ -857,7 +895,7 @@ void run(Strings args)
 {
     bool slave = false;
     bool daemon = false;
-    
+
     for (Strings::iterator i = args.begin(); i != args.end(); ) {
         string arg = *i++;
         if (arg == "--slave") slave = true;