From 76a8978c3e487d32b80b8cb55c07e69b10453a95 Mon Sep 17 00:00:00 2001 From: Marcin Matlaszek Date: Wed, 22 Nov 2017 00:51:39 +0100 Subject: [PATCH] Make starting & cleaning process group Windows compatible. --- client/driver/executor/executor.go | 13 ++++++++++++- client/driver/executor/executor_linux.go | 9 --------- client/driver/executor/executor_unix.go | 10 ++++++++++ client/driver/raw_exec.go | 4 ++-- client/driver/utils.go | 10 ---------- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/client/driver/executor/executor.go b/client/driver/executor/executor.go index 41153730b..62a67c1bd 100644 --- a/client/driver/executor/executor.go +++ b/client/driver/executor/executor.go @@ -448,6 +448,17 @@ func ClientCleanup(ic *dstructs.IsolationConfig, pid int) error { return clientCleanup(ic, pid) } +// Cleanup any still hanging user processes +func (e *UniversalExecutor) cleanupUserLeftovers(proc *os.Process) error { + // If new process group was created upon command execution + // we can kill the whole process group now to cleanup any leftovers. + if e.cmd.SysProcAttr != nil && e.cmd.SysProcAttr.Setpgid { + return syscall.Kill(-proc.Pid, syscall.SIGKILL) + } else { + return proc.Kill() + } +} + // Exit cleans up the alloc directory, destroys resource container and kills the // user process func (e *UniversalExecutor) Exit() error { @@ -475,7 +486,7 @@ func (e *UniversalExecutor) Exit() error { if err != nil { e.logger.Printf("[ERR] executor: can't find process with pid: %v, err: %v", e.cmd.Process.Pid, err) - } else if err := proc.Kill(); err != nil && err.Error() != finishedErr { + } else if err := e.cleanupUserLeftovers(proc); err != nil && err.Error() != finishedErr { merr.Errors = append(merr.Errors, fmt.Errorf("can't kill process with pid: %v, err: %v", e.cmd.Process.Pid, err)) } diff --git a/client/driver/executor/executor_linux.go b/client/driver/executor/executor_linux.go index fe9600eb9..ef1de7ebc 100644 --- a/client/driver/executor/executor_linux.go +++ b/client/driver/executor/executor_linux.go @@ -331,15 +331,6 @@ func DestroyCgroup(groups *cgroupConfig.Cgroup, cgPaths map[string]string, execu return mErrs.ErrorOrNil() } -// configure new process group for child process -func (e *UniversalExecutor) setNewProcessGroup() error { - if e.cmd.SysProcAttr == nil { - e.cmd.SysProcAttr = &syscall.SysProcAttr{} - } - e.cmd.SysProcAttr.Setpgid = true - return nil -} - // getCgroupManager returns the correct libcontainer cgroup manager. func getCgroupManager(groups *cgroupConfig.Cgroup, paths map[string]string) cgroups.Manager { return &cgroupFs.Manager{Cgroups: groups, Paths: paths} diff --git a/client/driver/executor/executor_unix.go b/client/driver/executor/executor_unix.go index 90efa32e6..cf2fc3f33 100644 --- a/client/driver/executor/executor_unix.go +++ b/client/driver/executor/executor_unix.go @@ -5,6 +5,7 @@ package executor import ( "fmt" "io" + "syscall" syslog "github.com/RackSec/srslog" @@ -47,3 +48,12 @@ func (e *UniversalExecutor) collectLogs(we io.Writer, wo io.Writer) { } } } + +// configure new process group for child process +func (e *UniversalExecutor) setNewProcessGroup() error { + if e.cmd.SysProcAttr == nil { + e.cmd.SysProcAttr = &syscall.SysProcAttr{} + } + e.cmd.SysProcAttr.Setpgid = true + return nil +} diff --git a/client/driver/raw_exec.go b/client/driver/raw_exec.go index e8f6c5bd2..0cea2ea55 100644 --- a/client/driver/raw_exec.go +++ b/client/driver/raw_exec.go @@ -298,8 +298,8 @@ func (h *rawExecHandle) run() { ps, werr := h.executor.Wait() close(h.doneCh) if ps.ExitCode == 0 && werr != nil { - if e := killProcessGroup(h.userPid); e != nil { - h.logger.Printf("[ERR] driver.raw_exec: error killing user process group: %v", e) + if e := killProcess(h.userPid); e != nil { + h.logger.Printf("[ERR] driver.raw_exec: error killing user process: %v", e) } } diff --git a/client/driver/utils.go b/client/driver/utils.go index c40387007..5fba8071f 100644 --- a/client/driver/utils.go +++ b/client/driver/utils.go @@ -8,7 +8,6 @@ import ( "os/exec" "path/filepath" "strings" - "syscall" "time" "github.com/hashicorp/consul-template/signals" @@ -111,15 +110,6 @@ func killProcess(pid int) error { return proc.Kill() } -// killProcessGroup kills a process group with the given pid -func killProcessGroup(pid int) error { - proc, err := os.FindProcess(pid) - if err != nil { - return err - } - return syscall.Kill(-proc.Pid, syscall.SIGKILL) -} - // destroyPlugin kills the plugin with the given pid and also kills the user // process func destroyPlugin(pluginPid int, userPid int) error {