SSHMaster: Make thread-safe
This commit is contained in:
parent
d3eb1cf3bb
commit
8490ee37a6
2 changed files with 29 additions and 17 deletions
|
@ -4,7 +4,7 @@ namespace nix {
|
||||||
|
|
||||||
std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string & command)
|
std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string & command)
|
||||||
{
|
{
|
||||||
startMaster();
|
Path socketPath = startMaster();
|
||||||
|
|
||||||
Pipe in, out;
|
Pipe in, out;
|
||||||
in.create();
|
in.create();
|
||||||
|
@ -27,7 +27,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
|
||||||
args.insert(args.end(), {"-i", keyFile});
|
args.insert(args.end(), {"-i", keyFile});
|
||||||
if (compress)
|
if (compress)
|
||||||
args.push_back("-C");
|
args.push_back("-C");
|
||||||
if (useMaster)
|
if (socketPath != "")
|
||||||
args.insert(args.end(), {"-S", socketPath});
|
args.insert(args.end(), {"-S", socketPath});
|
||||||
args.push_back(command);
|
args.push_back(command);
|
||||||
execvp(args.begin()->c_str(), stringsToCharPtrs(args).data());
|
execvp(args.begin()->c_str(), stringsToCharPtrs(args).data());
|
||||||
|
@ -45,18 +45,22 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSHMaster::startMaster()
|
Path SSHMaster::startMaster()
|
||||||
{
|
{
|
||||||
if (!useMaster || sshMaster != -1) return;
|
if (!useMaster) return "";
|
||||||
|
|
||||||
tmpDir = std::make_unique<AutoDelete>(createTempDir("", "nix", true, true, 0700));
|
auto state(state_.lock());
|
||||||
|
|
||||||
socketPath = (Path) *tmpDir + "/ssh.sock";
|
if (state->sshMaster != -1) return state->socketPath;
|
||||||
|
|
||||||
|
state->tmpDir = std::make_unique<AutoDelete>(createTempDir("", "nix", true, true, 0700));
|
||||||
|
|
||||||
|
state->socketPath = (Path) *state->tmpDir + "/ssh.sock";
|
||||||
|
|
||||||
Pipe out;
|
Pipe out;
|
||||||
out.create();
|
out.create();
|
||||||
|
|
||||||
sshMaster = startProcess([&]() {
|
state->sshMaster = startProcess([&]() {
|
||||||
restoreSignals();
|
restoreSignals();
|
||||||
|
|
||||||
close(out.readSide.get());
|
close(out.readSide.get());
|
||||||
|
@ -65,7 +69,7 @@ void SSHMaster::startMaster()
|
||||||
throw SysError("duping over stdout");
|
throw SysError("duping over stdout");
|
||||||
|
|
||||||
Strings args =
|
Strings args =
|
||||||
{ "ssh", host.c_str(), "-M", "-N", "-S", socketPath
|
{ "ssh", host.c_str(), "-M", "-N", "-S", state->socketPath
|
||||||
, "-o", "LocalCommand=echo started"
|
, "-o", "LocalCommand=echo started"
|
||||||
, "-o", "PermitLocalCommand=yes"
|
, "-o", "PermitLocalCommand=yes"
|
||||||
};
|
};
|
||||||
|
@ -88,6 +92,8 @@ void SSHMaster::startMaster()
|
||||||
|
|
||||||
if (reply != "started")
|
if (reply != "started")
|
||||||
throw Error("failed to start SSH master connection to ‘%s’", host);
|
throw Error("failed to start SSH master connection to ‘%s’", host);
|
||||||
|
|
||||||
|
return state->socketPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
#include "sync.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -8,13 +9,19 @@ class SSHMaster
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string host;
|
const std::string host;
|
||||||
std::string keyFile;
|
const std::string keyFile;
|
||||||
bool useMaster;
|
const bool useMaster;
|
||||||
bool compress;
|
const bool compress;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
Pid sshMaster;
|
Pid sshMaster;
|
||||||
std::unique_ptr<AutoDelete> tmpDir;
|
std::unique_ptr<AutoDelete> tmpDir;
|
||||||
Path socketPath;
|
Path socketPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
Sync<State> state_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -34,8 +41,7 @@ public:
|
||||||
|
|
||||||
std::unique_ptr<Connection> startCommand(const std::string & command);
|
std::unique_ptr<Connection> startCommand(const std::string & command);
|
||||||
|
|
||||||
void startMaster();
|
Path startMaster();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue