]> source.dussan.org Git - gitea.git/commitdiff
Prevent zombie processes (#16314)
authorzeripath <art27@cantab.net>
Wed, 30 Jun 2021 20:07:23 +0000 (21:07 +0100)
committerGitHub <noreply@github.com>
Wed, 30 Jun 2021 20:07:23 +0000 (22:07 +0200)
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>
cmd/serv.go
modules/markup/external/external.go
modules/ssh/ssh.go

index 1c9f5dc44e9d32553f77b2bdfd79a12eaea2d80f..40f8b89c9a98b44f99ca20b0483a5e839e077304 100644 (file)
@@ -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
index c849f505e7ee8e4087288ef44604e33241338d73..e35a1b99c0fd83497d8146c049637b5e57014b81 100644 (file)
@@ -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,
index bcaae5a1806dc1c4600f0f3cfc78f3c560893ed0..c0897377c56fdd533b0533cab004681b779c7a0d 100644 (file)
@@ -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,