Merge pull request #3572 from emate/master

Create new process group on process startup.
This commit is contained in:
Michael Schurter 2018-04-13 11:56:38 -07:00 committed by GitHub
commit 3836b8a335
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 1 deletions

View file

@ -227,6 +227,11 @@ func (e *UniversalExecutor) LaunchCmd(command *ExecCommand) (*ProcessState, erro
// set the task dir as the working directory for the command
e.cmd.Dir = e.ctx.TaskDir
// start command in separate process group
if err := e.setNewProcessGroup(); err != nil {
return nil, err
}
// configuring the chroot, resource container, and start the plugin
// process in the chroot.
if err := e.configureIsolation(); err != nil {
@ -435,6 +440,10 @@ var (
// finishedErr is the error message received when trying to kill and already
// exited process.
finishedErr = "os: process already finished"
// noSuchProcessErr is the error message received when trying to kill a non
// existing process (e.g. when killing a process group).
noSuchProcessErr = "no such process"
)
// ClientCleanup is the cleanup routine that a Nomad Client uses to remove the
@ -443,6 +452,20 @@ func ClientCleanup(ic *dstructs.IsolationConfig, pid int) error {
return clientCleanup(ic, pid)
}
// Cleanup any still hanging user processes
func (e *UniversalExecutor) cleanupChildProcesses(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 {
if err := syscall.Kill(-proc.Pid, syscall.SIGKILL); err != nil && err.Error() != noSuchProcessErr {
return err
}
return nil
} else {
return proc.Kill()
}
}
// Exit cleans up the alloc directory, destroys resource container and kills the
// user process
func (e *UniversalExecutor) Exit() error {
@ -470,7 +493,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.cleanupChildProcesses(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))
}

View file

@ -5,6 +5,8 @@ package executor
import (
"fmt"
"io"
"runtime"
"syscall"
syslog "github.com/RackSec/srslog"
@ -47,3 +49,16 @@ func (e *UniversalExecutor) collectLogs(we io.Writer, wo io.Writer) {
}
}
}
// configure new process group for child process
func (e *UniversalExecutor) setNewProcessGroup() error {
// We need to check that as build flags includes windows for this file
if runtime.GOOS == "windows" {
return nil
}
if e.cmd.SysProcAttr == nil {
e.cmd.SysProcAttr = &syscall.SysProcAttr{}
}
e.cmd.SysProcAttr.Setpgid = true
return nil
}