Factor out the unix domain socket-specific code from RemoteStore

This commit is contained in:
Shea Levy 2016-09-02 14:15:04 -04:00
parent 7d4ccd9b17
commit 0f39633290
5 changed files with 69 additions and 36 deletions

View file

@ -37,7 +37,8 @@ namespace nix {
LocalStore::LocalStore(const Params & params) LocalStore::LocalStore(const Params & params)
: LocalFSStore(params) : Store(params)
, LocalFSStore(params)
, realStoreDir(get(params, "real", rootDir != "" ? rootDir + "/nix/store" : storeDir)) , realStoreDir(get(params, "real", rootDir != "" ? rootDir + "/nix/store" : storeDir))
, dbDir(stateDir + "/db") , dbDir(stateDir + "/db")
, linksDir(realStoreDir + "/.links") , linksDir(realStoreDir + "/.links")

View file

@ -38,9 +38,9 @@ template<class T> T readStorePaths(Store & store, Source & from)
template PathSet 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) RemoteStore::RemoteStore(const Params & params, size_t maxConnections)
: LocalFSStore(params) : Store(params)
, connections(make_ref<Pool<Connection>>( , connections(make_ref<Pool<Connection>>(
maxConnections, maxConnections,
[this]() { return openConnection(); }, [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"; return "daemon";
} }
ref<RemoteStore::Connection> RemoteStore::openConnection() ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
{ {
auto conn = make_ref<Connection>(); auto conn = make_ref<Connection>();
@ -84,46 +92,52 @@ ref<RemoteStore::Connection> RemoteStore::openConnection()
conn->from.fd = conn->fd.get(); conn->from.fd = conn->fd.get();
conn->to.fd = conn->fd.get(); conn->to.fd = conn->fd.get();
/* Send the magic greeting, check for the reply. */ initConnection(*conn);
try {
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); return conn;
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)
throw Error("the Nix daemon version is too old");
conn->to << PROTOCOL_VERSION;
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 14) {
int cpu = settings.lockCPU ? lockToCurrentCPU() : -1;
if (cpu != -1)
conn->to << 1 << cpu;
else
conn->to << 0;
} }
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 11)
conn->to << false;
conn->processStderr(); 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);
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))
throw Error("Nix daemon protocol version not supported");
if (GET_PROTOCOL_MINOR(conn.daemonVersion) < 10)
throw Error("the Nix daemon version is too old");
conn.to << PROTOCOL_VERSION;
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 14) {
int cpu = settings.lockCPU ? lockToCurrentCPU() : -1;
if (cpu != -1)
conn.to << 1 << cpu;
else
conn.to << 0;
}
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 11)
conn.to << false;
conn.processStderr();
} }
catch (Error & e) { catch (Error & e) {
throw Error(format("cannot start daemon worker: %1%") % e.msg()); throw Error(format("cannot start daemon worker: %1%") % e.msg());
} }
setOptions(conn); setOptions(conn);
return conn;
} }
void RemoteStore::setOptions(ref<Connection> conn) void RemoteStore::setOptions(Connection & conn)
{ {
conn->to << wopSetOptions conn.to << wopSetOptions
<< settings.keepFailed << settings.keepFailed
<< settings.keepGoing << settings.keepGoing
<< settings.tryFallback << settings.tryFallback
@ -137,16 +151,16 @@ void RemoteStore::setOptions(ref<Connection> conn)
<< settings.buildCores << settings.buildCores
<< settings.useSubstitutes; << settings.useSubstitutes;
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 12) { if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) {
Settings::SettingsMap overrides = settings.getOverrides(); Settings::SettingsMap overrides = settings.getOverrides();
if (overrides["ssh-auth-sock"] == "") if (overrides["ssh-auth-sock"] == "")
overrides["ssh-auth-sock"] = getEnv("SSH_AUTH_SOCK"); overrides["ssh-auth-sock"] = getEnv("SSH_AUTH_SOCK");
conn->to << overrides.size(); conn.to << overrides.size();
for (auto & i : overrides) 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 { try {
to.flush(); to.flush();
fd = -1;
} catch (...) { } catch (...) {
ignoreException(); ignoreException();
} }

View file

@ -18,7 +18,7 @@ template<typename T> class Pool;
/* FIXME: RemoteStore is a misnomer - should be something like /* FIXME: RemoteStore is a misnomer - should be something like
DaemonStore. */ DaemonStore. */
class RemoteStore : public LocalFSStore class RemoteStore : public virtual Store
{ {
public: public:
@ -26,8 +26,6 @@ public:
/* Implementations of abstract store API methods. */ /* Implementations of abstract store API methods. */
std::string getUri() override;
bool isValidPathUncached(const Path & path) override; bool isValidPathUncached(const Path & path) override;
PathSet queryValidPaths(const PathSet & paths) override; PathSet queryValidPaths(const PathSet & paths) override;
@ -84,11 +82,10 @@ public:
void addSignatures(const Path & storePath, const StringSet & sigs) override; void addSignatures(const Path & storePath, const StringSet & sigs) override;
private: protected:
struct Connection struct Connection
{ {
AutoCloseFD fd;
FdSink to; FdSink to;
FdSource from; FdSource from;
unsigned int daemonVersion; unsigned int daemonVersion;
@ -98,11 +95,33 @@ private:
void processStderr(Sink * sink = 0, Source * source = 0); void processStderr(Sink * sink = 0, Source * source = 0);
}; };
virtual ref<Connection> openConnection() = 0;
void setOptions(Connection & conn);
void initConnection(Connection & conn);
private:
ref<Pool<Connection>> connections; ref<Pool<Connection>> connections;
};
ref<Connection> openConnection(); class UDSRemoteStore : public LocalFSStore, public RemoteStore
{
public:
void setOptions(ref<Connection> conn); UDSRemoteStore(const Params & params, size_t maxConnections = std::numeric_limits<size_t>::max());
std::string getUri() override;
private:
struct Connection : RemoteStore::Connection
{
AutoCloseFD fd;
};
ref<RemoteStore::Connection> openConnection() override;
}; };

View file

@ -554,7 +554,7 @@ static RegisterStoreImplementation regStore([](
{ {
switch (getStoreType(uri, get(params, "state", settings.nixStateDir))) { switch (getStoreType(uri, get(params, "state", settings.nixStateDir))) {
case tDaemon: case tDaemon:
return std::shared_ptr<Store>(std::make_shared<RemoteStore>(params)); return std::shared_ptr<Store>(std::make_shared<UDSRemoteStore>(params));
case tLocal: case tLocal:
return std::shared_ptr<Store>(std::make_shared<LocalStore>(params)); return std::shared_ptr<Store>(std::make_shared<LocalStore>(params));
default: default:

View file

@ -526,7 +526,7 @@ protected:
}; };
class LocalFSStore : public Store class LocalFSStore : public virtual Store
{ {
public: public:
const Path rootDir; const Path rootDir;