mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
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.
This commit is contained in:
parent
30e4d7d6aa
commit
56e3ab0943
@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/pkg/netutil"
|
||||
@ -80,20 +81,39 @@ func (a *Agent) stop() error {
|
||||
if a.state != stateStarted {
|
||||
return nil
|
||||
}
|
||||
err := a.cmd.Process.Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = a.cmd.Process.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
err := sigtermAndWait(a.cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.state = stateStopped
|
||||
return nil
|
||||
}
|
||||
|
||||
func sigtermAndWait(cmd *exec.Cmd) error {
|
||||
err := cmd.Process.Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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.
|
||||
func (a *Agent) restart() error {
|
||||
a.cmd = exec.Command(a.cmd.Path, a.cmd.Args[1:]...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user