From f3441e6122c3ce8f81576bfe79897a638c8f82e2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Sep 2007 09:11:20 +0000 Subject: [PATCH] * Pass various options to the worker so that flags like -K or -j work in multi-user Nix (NIX-72). * Client/worker: exchange a protocol version number for future compatibility. --- src/libexpr/primops.cc | 3 +-- src/libstore/remote-store.cc | 23 +++++++++++++++++++++-- src/libstore/remote-store.hh | 2 ++ src/libstore/worker-protocol.hh | 8 ++++++-- src/nix-worker/nix-worker.cc | 20 +++++++++++++++++++- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 044eff657b..d0326a3e56 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -773,7 +773,6 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) if (matchAttrs(evaledExpr, attrs)){ Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("attr"))); string attr = evalStringNoCtx(state,e); - ATerm value; Expr r = makeSelect(evaledExpr, toATerm("value")); res.set(toATerm(attr), makeAttrRHS(r, makeNoPos())); } @@ -783,7 +782,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) } // for return makeAttrs(res); } catch (Error & e) { - e.addPrefix(format("while calling listToAttrs ")); + e.addPrefix(format("in `listToAttrs':\n")); throw; } } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index c5d13bf494..4d866071b1 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -53,18 +53,24 @@ RemoteStore::RemoteStore() from.fd = fdSocket; to.fd = fdSocket; - /* Send the magic greeting, check for the reply. */ try { writeInt(WORKER_MAGIC_1, to); - writeInt(verbosity, to); unsigned int magic = readInt(from); if (magic != WORKER_MAGIC_2) throw Error("protocol mismatch"); + + unsigned int daemonVersion = readInt(from); + if (GET_PROTOCOL_MAJOR(daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) + throw Error("Nix daemon protocol version not supported"); + writeInt(PROTOCOL_VERSION, to); processStderr(); + } catch (Error & e) { throw Error(format("cannot start worker (%1%)") % e.msg()); } + + setOptions(); } @@ -154,6 +160,19 @@ RemoteStore::~RemoteStore() } +void RemoteStore::setOptions() +{ + writeInt(wopSetOptions, to); + writeInt(keepFailed, to); + writeInt(keepGoing, to); + writeInt(tryFallback, to); + writeInt(verbosity, to); + writeInt(maxBuildJobs, to); + writeInt(maxSilentTime, to); + processStderr(); +} + + bool RemoteStore::isValidPath(const Path & path) { writeInt(wopIsValidPath, to); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 87850c4068..79a15e11ef 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -77,6 +77,8 @@ private: void forkSlave(); void connectToDaemon(); + + void setOptions(); }; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index f3b63151db..22f5973a96 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -5,8 +5,11 @@ namespace nix { -#define WORKER_MAGIC_1 0x6e697864 -#define WORKER_MAGIC_2 0x6478696e +#define WORKER_MAGIC_1 0x6e697863 +#define WORKER_MAGIC_2 0x6478696f + +#define PROTOCOL_VERSION 0x101 +#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) typedef enum { @@ -28,6 +31,7 @@ typedef enum { wopExportPath, wopImportPath, wopQueryDeriver, + wopSetOptions, } WorkerOp; diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index b9d5b1e263..9f387a4ec1 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -414,6 +414,19 @@ static void performOp(Source & from, Sink & to, unsigned int op) break; } + + case wopSetOptions: { + keepFailed = readInt(from) != 0; + keepGoing = readInt(from) != 0; + tryFallback = readInt(from) != 0; + verbosity = (Verbosity) readInt(from); + maxBuildJobs = readInt(from); + maxSilentTime = readInt(from); + startWork(); + stopWork(); + break; + } + default: throw Error(format("invalid operation %1%") % op); @@ -437,14 +450,19 @@ static void processConnection() /* Exchange the greeting. */ unsigned int magic = readInt(from); if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch"); - verbosity = (Verbosity) readInt(from); writeInt(WORKER_MAGIC_2, to); + writeInt(PROTOCOL_VERSION, to); + unsigned int clientVersion = readInt(from); + /* Send startup error messages to the client. */ startWork(); try { + /* If we can't accept clientVersion, then throw an error + *here* (not above). */ + /* Prevent users from doing something very dangerous. */ if (geteuid() == 0 && querySetting("build-users-group", "") == "")