mirror of https://github.com/rclone/rclone
Fix zombie SSH processes by storing the first session in sshClientExternal
The real issue was that sshClientExternal.session was never assigned, so Wait() always returned nil without waiting for the SSH process to exit. This caused zombie processes because the process was never reaped. The fix: - Store the first session created in NewSession() to s.session - This allows Wait() to actually wait for the SSH process - The sync.Once pattern is still useful for thread-safety - Updated comments to reflect the correct behavior Fixes the zombie process issue reported in rclone/rclone#8929 Co-authored-by: ncw <536803+ncw@users.noreply.github.com>
This commit is contained in:
parent
a58efc1544
commit
46bc876085
|
|
@ -51,6 +51,9 @@ func (s *sshClientExternal) Close() error {
|
|||
func (s *sshClientExternal) NewSession() (sshSession, error) {
|
||||
session := s.f.newSSHSessionExternal()
|
||||
if s.session == nil {
|
||||
// Store the first session so Wait() and Close() can use it
|
||||
s.session = session
|
||||
} else {
|
||||
fs.Debugf(s.f, "ssh external: creating additional session")
|
||||
}
|
||||
return session, nil
|
||||
|
|
@ -178,11 +181,9 @@ func (s *sshSessionExternal) exited() bool {
|
|||
|
||||
// Wait for the command to exit
|
||||
func (s *sshSessionExternal) Wait() error {
|
||||
// Use sync.Once to ensure we only wait for the process once
|
||||
// This prevents zombie processes that occur when Wait() is called multiple times
|
||||
// Use sync.Once to ensure we only wait for the process once.
|
||||
// This is safe even if Wait() is called from multiple goroutines.
|
||||
s.waitOnce.Do(func() {
|
||||
// Always call cmd.Wait() to properly reap the process
|
||||
// even if it has already exited
|
||||
s.waitErr = s.cmd.Wait()
|
||||
if s.waitErr == nil {
|
||||
fs.Debugf(s.f, "ssh external: command exited OK")
|
||||
|
|
|
|||
Loading…
Reference in New Issue