sshbytestream & IOCommand: fix handling of dead child process
SSH catches SIGTERM, tears down its connection, then exits with platform-specific exit code.
This commit is contained in:
+43
-5
@@ -2,9 +2,12 @@ package sshbytestream
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/zrepl/zrepl/util"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/zrepl/zrepl/util"
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
@@ -53,7 +56,11 @@ func (f IncomingReadWriteCloser) Close() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func Outgoing(remote SSHTransport) (c *util.IOCommand, err error) {
|
||||
type OutgoingSSHByteStream struct {
|
||||
c *util.IOCommand
|
||||
}
|
||||
|
||||
func Outgoing(remote SSHTransport) (s OutgoingSSHByteStream, err error) {
|
||||
|
||||
sshArgs := make([]string, 0, 2*len(remote.Options)+4)
|
||||
sshArgs = append(sshArgs,
|
||||
@@ -73,13 +80,44 @@ func Outgoing(remote SSHTransport) (c *util.IOCommand, err error) {
|
||||
sshCommand = SSHCommand
|
||||
}
|
||||
|
||||
if c, err = util.NewIOCommand(sshCommand, sshArgs, util.IOCommandStderrBufSize); err != nil {
|
||||
if s.c, err = util.NewIOCommand(sshCommand, sshArgs, util.IOCommandStderrBufSize); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Clear environment of cmd, ssh shall not rely on SSH_AUTH_SOCK, etc.
|
||||
c.Cmd.Env = []string{}
|
||||
s.c.Cmd.Env = []string{}
|
||||
|
||||
err = s.c.Start()
|
||||
return
|
||||
}
|
||||
|
||||
func (s OutgoingSSHByteStream) Read(p []byte) (n int, err error) {
|
||||
return s.c.Read(p)
|
||||
}
|
||||
|
||||
func (s OutgoingSSHByteStream) Write(p []byte) (n int, err error) {
|
||||
return s.c.Write(p)
|
||||
}
|
||||
|
||||
func (s OutgoingSSHByteStream) Close() (err error) {
|
||||
err = s.c.Close()
|
||||
if err == nil || s.c.ExitResult == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// SSH catches SIGTERM and has different exit codes on different platforms
|
||||
ws := s.c.ExitResult.WaitStatus
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
if ws.ExitStatus() == 128+int(syscall.SIGTERM) { // OpenSSH_7.5p1, OpenSSL 1.1.0f 25 May 2017 Arch Linux
|
||||
err = nil
|
||||
}
|
||||
case "freebsd": // OpenSSH_7.2p2, OpenSSL 1.0.2k-freebsd 26 Jan 2017
|
||||
if ws.ExitStatus() == 255 {
|
||||
err = nil
|
||||
}
|
||||
default: // TODO
|
||||
}
|
||||
|
||||
err = c.Start()
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user