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());