From 4e4775ae8c8cf8de5fbf6dc041613dc98202fb30 Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Tue, 6 Jan 2026 17:14:51 +0100
Subject: [PATCH 1/2] libstore: Improve SSH connection sharing
---
src/libstore/include/nix/store/ssh.hh | 2 +-
src/libstore/ssh.cc | 15 ++++++++-------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/libstore/include/nix/store/ssh.hh b/src/libstore/include/nix/store/ssh.hh
index 574cb5cf414..8a8ce5dc9d5 100644
--- a/src/libstore/include/nix/store/ssh.hh
+++ b/src/libstore/include/nix/store/ssh.hh
@@ -40,7 +40,7 @@ private:
Sync state_;
void addCommonSSHOpts(Strings & args);
- bool isMasterRunning();
+ bool isMasterRunning(Path socketPath);
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
Path startMaster();
diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc
index 1a99083669c..8baf3dc5414 100644
--- a/src/libstore/ssh.cc
+++ b/src/libstore/ssh.cc
@@ -115,9 +115,11 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
args.push_back("-oLocalCommand=echo started");
}
-bool SSHMaster::isMasterRunning()
+bool SSHMaster::isMasterRunning(Path socketPath)
{
- Strings args = {"-O", "check", hostnameAndUser};
+ assert(useMaster);
+
+ Strings args = {"-O", "check", hostnameAndUser, "-S", socketPath};
addCommonSSHOpts(args);
auto res = runProgram(RunOptions{.program = "ssh", .args = args, .mergeStderrToStdout = true});
@@ -184,8 +186,7 @@ std::unique_ptr SSHMaster::startCommand(Strings && comman
if (!fakeSSH) {
args = {"ssh", hostnameAndUser.c_str(), "-x"};
addCommonSSHOpts(args);
- if (socketPath != "")
- args.insert(args.end(), {"-S", socketPath});
+ args.insert(args.end(), {"-S", socketPath});
if (verbosity >= lvlChatty)
args.push_back("-v");
args.splice(args.end(), std::move(extraSshArgs));
@@ -206,7 +207,7 @@ std::unique_ptr SSHMaster::startCommand(Strings && comman
// Wait for the SSH connection to be established,
// So that we don't overwrite the password prompt with our progress bar.
- if (!fakeSSH && !useMaster && !isMasterRunning()) {
+ if (!fakeSSH && !(useMaster && isMasterRunning(socketPath))) {
std::string reply;
try {
reply = readLine(out.readSide.get());
@@ -231,7 +232,7 @@ std::unique_ptr SSHMaster::startCommand(Strings && comman
Path SSHMaster::startMaster()
{
if (!useMaster)
- return "";
+ return "none";
auto state(state_.lock());
@@ -248,7 +249,7 @@ Path SSHMaster::startMaster()
auto suspension = logger->suspend();
- if (isMasterRunning())
+ if (isMasterRunning(state->socketPath))
return state->socketPath;
state->sshMaster = startProcess(
From e5f6bb93d3953f8a5be5833f4e3de9f0e25238be Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Wed, 7 Jan 2026 15:50:02 +0100
Subject: [PATCH 2/2] libstore/ssh: Move -S into addCommonSSHOpts
---
src/libstore/include/nix/store/ssh.hh | 2 +-
src/libstore/ssh.cc | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/libstore/include/nix/store/ssh.hh b/src/libstore/include/nix/store/ssh.hh
index 8a8ce5dc9d5..03a67c45472 100644
--- a/src/libstore/include/nix/store/ssh.hh
+++ b/src/libstore/include/nix/store/ssh.hh
@@ -39,7 +39,7 @@ private:
Sync state_;
- void addCommonSSHOpts(Strings & args);
+ void addCommonSSHOpts(Strings & args, Path socketPath);
bool isMasterRunning(Path socketPath);
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc
index 8baf3dc5414..e8309e75b27 100644
--- a/src/libstore/ssh.cc
+++ b/src/libstore/ssh.cc
@@ -89,7 +89,7 @@ SSHMaster::SSHMaster(
checkValidAuthority(authority);
}
-void SSHMaster::addCommonSSHOpts(Strings & args)
+void SSHMaster::addCommonSSHOpts(Strings & args, Path socketPath)
{
auto sshArgs = getNixSshOpts();
args.insert(args.end(), sshArgs.begin(), sshArgs.end());
@@ -113,14 +113,15 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
// the remote session won't be garbled if the local command is slow.
args.push_back("-oPermitLocalCommand=yes");
args.push_back("-oLocalCommand=echo started");
+ args.insert(args.end(), {"-S", socketPath});
}
bool SSHMaster::isMasterRunning(Path socketPath)
{
assert(useMaster);
- Strings args = {"-O", "check", hostnameAndUser, "-S", socketPath};
- addCommonSSHOpts(args);
+ Strings args = {"-O", "check", hostnameAndUser};
+ addCommonSSHOpts(args, socketPath);
auto res = runProgram(RunOptions{.program = "ssh", .args = args, .mergeStderrToStdout = true});
return res.first == 0;
@@ -185,8 +186,7 @@ std::unique_ptr SSHMaster::startCommand(Strings && comman
if (!fakeSSH) {
args = {"ssh", hostnameAndUser.c_str(), "-x"};
- addCommonSSHOpts(args);
- args.insert(args.end(), {"-S", socketPath});
+ addCommonSSHOpts(args, socketPath);
if (verbosity >= lvlChatty)
args.push_back("-v");
args.splice(args.end(), std::move(extraSshArgs));
@@ -261,10 +261,10 @@ Path SSHMaster::startMaster()
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("duping over stdout");
- Strings args = {"ssh", hostnameAndUser.c_str(), "-M", "-N", "-S", state->socketPath};
+ Strings args = {"ssh", hostnameAndUser.c_str(), "-M", "-N"};
if (verbosity >= lvlChatty)
args.push_back("-v");
- addCommonSSHOpts(args);
+ addCommonSSHOpts(args, state->socketPath);
auto env = createSSHEnv();
nix::execvpe(args.begin()->c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(env).data());