Browse Source

etcd-agent: tidy cleanup before SIGKILL

https://github.com/golang/go/blob/master/src/os/exec_posix.go#L18 shows that
cmd.Process.Kill calls syscall.SIGKILL to the command. But
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_01.html explains
'If you send a SIGKILL to a process, you remove any chance for the process to
do a tidy cleanup and shutdown, which might have unfortunate consequences.'
This sends SIGTERM, SIGINT syscalls to the PID so that the process could
have more time to clean up the resources.

Related to https://github.com/coreos/etcd/issues/4517.
Gyu-Ho Lee 9 years ago
parent
commit
56e3ab0943
1 changed files with 25 additions and 5 deletions
  1. 25 5
      tools/functional-tester/etcd-agent/agent.go

+ 25 - 5
tools/functional-tester/etcd-agent/agent.go

@@ -21,6 +21,7 @@ import (
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"path"
 	"path"
+	"syscall"
 	"time"
 	"time"
 
 
 	"github.com/coreos/etcd/pkg/netutil"
 	"github.com/coreos/etcd/pkg/netutil"
@@ -80,18 +81,37 @@ func (a *Agent) stop() error {
 	if a.state != stateStarted {
 	if a.state != stateStarted {
 		return nil
 		return nil
 	}
 	}
-	err := a.cmd.Process.Kill()
+
+	err := sigtermAndWait(a.cmd)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	_, err = a.cmd.Process.Wait()
+
+	a.state = stateStopped
+	return nil
+}
+
+func sigtermAndWait(cmd *exec.Cmd) error {
+	err := cmd.Process.Signal(syscall.SIGTERM)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
-
 	}
 	}
 
 
-	a.state = stateStopped
-	return nil
+	errc := make(chan error)
+	go func() {
+		_, err := cmd.Process.Wait()
+		errc <- err
+		close(errc)
+	}()
+
+	select {
+	case <-time.After(5 * time.Second):
+		cmd.Process.Kill()
+	case err := <-errc:
+		return err
+	}
+	err = <-errc
+	return err
 }
 }
 
 
 // restart restarts the stopped etcd process.
 // restart restarts the stopped etcd process.