diff options
author | zeripath <art27@cantab.net> | 2021-06-30 21:07:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-30 22:07:23 +0200 |
commit | 302e8b6d02dc9ccac00284b3cdf9a69c001882c0 (patch) | |
tree | fd8a57a78924df719b8c6771d59c6577b163b659 | |
parent | 365c4e9316bbcc8bdf9cf68ef237bf18ae8db315 (diff) | |
download | gitea-302e8b6d02dc9ccac00284b3cdf9a69c001882c0.tar.gz gitea-302e8b6d02dc9ccac00284b3cdf9a69c001882c0.zip |
Prevent zombie processes (#16314)
Unfortunately go doesn't always ensure that execd processes are completely
waited for. On linux this means that zombie processes can occur.
This PR ensures that these are waited for by using signal notifier in serv and
passing a context elsewhere.
Signed-off-by: Andrew Thornton <art27@cantab.net>
-rw-r--r-- | cmd/serv.go | 26 | ||||
-rw-r--r-- | modules/markup/external/external.go | 10 | ||||
-rw-r--r-- | modules/ssh/ssh.go | 2 |
3 files changed, 34 insertions, 4 deletions
diff --git a/cmd/serv.go b/cmd/serv.go index 1c9f5dc44e..40f8b89c9a 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -6,14 +6,17 @@ package cmd import ( + "context" "fmt" "net/http" "net/url" "os" "os/exec" + "os/signal" "regexp" "strconv" "strings" + "syscall" "time" "code.gitea.io/gitea/models" @@ -273,12 +276,31 @@ func runServ(c *cli.Context) error { verb = strings.Replace(verb, "-", " ", 1) } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + // install notify + signalChannel := make(chan os.Signal, 1) + + signal.Notify( + signalChannel, + syscall.SIGINT, + syscall.SIGTERM, + ) + select { + case <-signalChannel: + case <-ctx.Done(): + } + cancel() + signal.Reset() + }() + var gitcmd *exec.Cmd verbs := strings.Split(verb, " ") if len(verbs) == 2 { - gitcmd = exec.Command(verbs[0], verbs[1], repoPath) + gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath) } else { - gitcmd = exec.Command(verb, repoPath) + gitcmd = exec.CommandContext(ctx, verb, repoPath) } gitcmd.Dir = setting.RepoRootPath diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go index c849f505e7..e35a1b99c0 100644 --- a/modules/markup/external/external.go +++ b/modules/markup/external/external.go @@ -5,6 +5,7 @@ package external import ( + "context" "fmt" "io" "io/ioutil" @@ -15,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" ) @@ -96,7 +98,13 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io. args = append(args, f.Name()) } - cmd := exec.Command(commands[0], args...) + processCtx, cancel := context.WithCancel(ctx.Ctx) + defer cancel() + + pid := process.GetManager().Add(fmt.Sprintf("Render [%s] for %s", commands[0], ctx.URLPrefix), cancel) + defer process.GetManager().Remove(pid) + + cmd := exec.CommandContext(processCtx, commands[0], args...) cmd.Env = append( os.Environ(), "GITEA_PREFIX_SRC="+ctx.URLPrefix, diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index bcaae5a180..c0897377c5 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -66,7 +66,7 @@ func sessionHandler(session ssh.Session) { args := []string{"serv", "key-" + keyID, "--config=" + setting.CustomConf} log.Trace("SSH: Arguments: %v", args) - cmd := exec.Command(setting.AppPath, args...) + cmd := exec.CommandContext(session.Context(), setting.AppPath, args...) cmd.Env = append( os.Environ(), "SSH_ORIGINAL_COMMAND="+command, |