From 0f3963329018d9cf930e2a0e2b0ec2f4e26b40b3 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Fri, 2 Sep 2016 14:15:04 -0400 Subject: [PATCH] Factor out the unix domain socket-specific code from RemoteStore --- src/libstore/local-store.cc | 3 +- src/libstore/remote-store.cc | 65 +++++++++++++++++++++--------------- src/libstore/remote-store.hh | 33 ++++++++++++++---- src/libstore/store-api.cc | 2 +- src/libstore/store-api.hh | 2 +- 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 10056f2f1..272d48741 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -37,7 +37,8 @@ namespace nix { LocalStore::LocalStore(const Params & params) - : LocalFSStore(params) + : Store(params) + , LocalFSStore(params) , realStoreDir(get(params, "real", rootDir != "" ? rootDir + "/nix/store" : storeDir)) , dbDir(stateDir + "/db") , linksDir(realStoreDir + "/.links") diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 94075f3b9..232f62e7a 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -38,9 +38,9 @@ template T readStorePaths(Store & store, Source & from) template PathSet readStorePaths(Store & store, Source & from); - +/* TODO: Separate these store impls into different files, give them better names */ RemoteStore::RemoteStore(const Params & params, size_t maxConnections) - : LocalFSStore(params) + : Store(params) , connections(make_ref>( maxConnections, [this]() { return openConnection(); }, @@ -50,13 +50,21 @@ RemoteStore::RemoteStore(const Params & params, size_t maxConnections) } -std::string RemoteStore::getUri() +UDSRemoteStore::UDSRemoteStore(const Params & params, size_t maxConnections) + : Store(params) + , LocalFSStore(params) + , RemoteStore(params, maxConnections) +{ +} + + +std::string UDSRemoteStore::getUri() { return "daemon"; } -ref RemoteStore::openConnection() +ref UDSRemoteStore::openConnection() { auto conn = make_ref(); @@ -84,46 +92,52 @@ ref RemoteStore::openConnection() conn->from.fd = conn->fd.get(); conn->to.fd = conn->fd.get(); + initConnection(*conn); + + return conn; +} + + +void RemoteStore::initConnection(Connection & conn) +{ /* Send the magic greeting, check for the reply. */ try { - conn->to << WORKER_MAGIC_1; - conn->to.flush(); - unsigned int magic = readInt(conn->from); + conn.to << WORKER_MAGIC_1; + conn.to.flush(); + unsigned int magic = readInt(conn.from); if (magic != WORKER_MAGIC_2) throw Error("protocol mismatch"); - conn->daemonVersion = readInt(conn->from); - if (GET_PROTOCOL_MAJOR(conn->daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) + conn.daemonVersion = readInt(conn.from); + if (GET_PROTOCOL_MAJOR(conn.daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION)) throw Error("Nix daemon protocol version not supported"); - if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 10) + if (GET_PROTOCOL_MINOR(conn.daemonVersion) < 10) throw Error("the Nix daemon version is too old"); - conn->to << PROTOCOL_VERSION; + conn.to << PROTOCOL_VERSION; - if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 14) { + if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 14) { int cpu = settings.lockCPU ? lockToCurrentCPU() : -1; if (cpu != -1) - conn->to << 1 << cpu; + conn.to << 1 << cpu; else - conn->to << 0; + conn.to << 0; } - if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 11) - conn->to << false; + if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 11) + conn.to << false; - conn->processStderr(); + conn.processStderr(); } catch (Error & e) { throw Error(format("cannot start daemon worker: %1%") % e.msg()); } setOptions(conn); - - return conn; } -void RemoteStore::setOptions(ref conn) +void RemoteStore::setOptions(Connection & conn) { - conn->to << wopSetOptions + conn.to << wopSetOptions << settings.keepFailed << settings.keepGoing << settings.tryFallback @@ -137,16 +151,16 @@ void RemoteStore::setOptions(ref conn) << settings.buildCores << settings.useSubstitutes; - if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 12) { + if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) { Settings::SettingsMap overrides = settings.getOverrides(); if (overrides["ssh-auth-sock"] == "") overrides["ssh-auth-sock"] = getEnv("SSH_AUTH_SOCK"); - conn->to << overrides.size(); + conn.to << overrides.size(); for (auto & i : overrides) - conn->to << i.first << i.second; + conn.to << i.first << i.second; } - conn->processStderr(); + conn.processStderr(); } @@ -528,7 +542,6 @@ RemoteStore::Connection::~Connection() { try { to.flush(); - fd = -1; } catch (...) { ignoreException(); } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index e756805ea..a69a4f2a3 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -18,7 +18,7 @@ template class Pool; /* FIXME: RemoteStore is a misnomer - should be something like DaemonStore. */ -class RemoteStore : public LocalFSStore +class RemoteStore : public virtual Store { public: @@ -26,8 +26,6 @@ public: /* Implementations of abstract store API methods. */ - std::string getUri() override; - bool isValidPathUncached(const Path & path) override; PathSet queryValidPaths(const PathSet & paths) override; @@ -84,11 +82,10 @@ public: void addSignatures(const Path & storePath, const StringSet & sigs) override; -private: +protected: struct Connection { - AutoCloseFD fd; FdSink to; FdSource from; unsigned int daemonVersion; @@ -98,11 +95,33 @@ private: void processStderr(Sink * sink = 0, Source * source = 0); }; + virtual ref openConnection() = 0; + + void setOptions(Connection & conn); + + void initConnection(Connection & conn); + +private: + ref> connections; +}; - ref openConnection(); +class UDSRemoteStore : public LocalFSStore, public RemoteStore +{ +public: - void setOptions(ref conn); + UDSRemoteStore(const Params & params, size_t maxConnections = std::numeric_limits::max()); + + std::string getUri() override; + +private: + + struct Connection : RemoteStore::Connection + { + AutoCloseFD fd; + }; + + ref openConnection() override; }; diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 604f0dac8..1ce483ca9 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -554,7 +554,7 @@ static RegisterStoreImplementation regStore([]( { switch (getStoreType(uri, get(params, "state", settings.nixStateDir))) { case tDaemon: - return std::shared_ptr(std::make_shared(params)); + return std::shared_ptr(std::make_shared(params)); case tLocal: return std::shared_ptr(std::make_shared(params)); default: diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 3d8b4fbbb..ae1d51016 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -526,7 +526,7 @@ protected: }; -class LocalFSStore : public Store +class LocalFSStore : public virtual Store { public: const Path rootDir;