Browse Source

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>
tags/v1.15.0-rc1
zeripath 4 years ago committed by GitHub
parent
commit
302e8b6d02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      cmd/serv.go
  2. 10
      modules/markup/external/external.go
  3. 2
      modules/ssh/ssh.go

26
cmd/serv.go

@ -6,14 +6,17 @@
package cmd package cmd
import ( import (
"context"
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"os/exec" "os/exec"
"os/signal"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@ -273,12 +276,31 @@ func runServ(c *cli.Context) error {
verb = strings.Replace(verb, "-", " ", 1) 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 var gitcmd *exec.Cmd
verbs := strings.Split(verb, " ") verbs := strings.Split(verb, " ")
if len(verbs) == 2 { if len(verbs) == 2 {
gitcmd = exec.Command(verbs[0], verbs[1], repoPath) gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
} else { } else {
gitcmd = exec.Command(verb, repoPath) gitcmd = exec.CommandContext(ctx, verb, repoPath)
} }
gitcmd.Dir = setting.RepoRootPath gitcmd.Dir = setting.RepoRootPath

10
modules/markup/external/external.go vendored

@ -5,6 +5,7 @@
package external package external
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -15,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "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()) 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( cmd.Env = append(
os.Environ(), os.Environ(),
"GITEA_PREFIX_SRC="+ctx.URLPrefix, "GITEA_PREFIX_SRC="+ctx.URLPrefix,

2
modules/ssh/ssh.go

@ -66,7 +66,7 @@ func sessionHandler(session ssh.Session) {
args := []string{"serv", "key-" + keyID, "--config=" + setting.CustomConf} args := []string{"serv", "key-" + keyID, "--config=" + setting.CustomConf}
log.Trace("SSH: Arguments: %v", args) log.Trace("SSH: Arguments: %v", args)
cmd := exec.Command(setting.AppPath, args...) cmd := exec.CommandContext(session.Context(), setting.AppPath, args...)
cmd.Env = append( cmd.Env = append(
os.Environ(), os.Environ(),
"SSH_ORIGINAL_COMMAND="+command, "SSH_ORIGINAL_COMMAND="+command,

Loading…
Cancel
Save