From bbf6e9c8411871118312ef07ee6129c622fd7e6e Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 30 Jun 2021 19:06:16 +0100 Subject: [PATCH 1/2] Prevent zombie processes 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 --- cmd/serv.go | 26 ++++++++++++++++++++++++-- modules/markup/external/external.go | 11 ++++++++++- modules/ssh/ssh.go | 2 +- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index 1c9f5dc44e9d3..40f8b89c9a98b 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 c849f505e7ee8..5ae8388fd05a1 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,14 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io. args = append(args, f.Name()) } - cmd := exec.Command(commands[0], args...) + // FIXME this should use process + 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 bcaae5a1806dc..c0897377c56fd 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, From 7ad4cd59e826fda9e5f336aa99398ae0afbfd7a2 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 30 Jun 2021 19:26:38 +0100 Subject: [PATCH 2/2] Update modules/markup/external/external.go --- modules/markup/external/external.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go index 5ae8388fd05a1..e35a1b99c0fd8 100644 --- a/modules/markup/external/external.go +++ b/modules/markup/external/external.go @@ -98,7 +98,6 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io. args = append(args, f.Name()) } - // FIXME this should use process processCtx, cancel := context.WithCancel(ctx.Ctx) defer cancel()