Skip to content

Commit 1d04e86

Browse files
authored
Set Setpgid on child git processes (#19865)
When Gitea is running as PID 1 git will occassionally orphan child processes leading to (defunct) processes. This PR simply sets Setpgid to true on these child processes meaning that these defunct processes will also be correctly reaped. Fix #19077 Signed-off-by: Andrew Thornton <[email protected]>
1 parent 085924b commit 1d04e86

File tree

9 files changed

+44
-0
lines changed

9 files changed

+44
-0
lines changed

cmd/serv.go

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"code.gitea.io/gitea/modules/log"
2525
"code.gitea.io/gitea/modules/pprof"
2626
"code.gitea.io/gitea/modules/private"
27+
"code.gitea.io/gitea/modules/process"
2728
repo_module "code.gitea.io/gitea/modules/repository"
2829
"code.gitea.io/gitea/modules/setting"
2930
"code.gitea.io/gitea/services/lfs"
@@ -306,6 +307,7 @@ func runServ(c *cli.Context) error {
306307
}
307308
}
308309

310+
process.SetSysProcAttribute(gitcmd)
309311
gitcmd.Dir = setting.RepoRootPath
310312
gitcmd.Stdout = os.Stdout
311313
gitcmd.Stdin = os.Stdin

modules/git/blame.go

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla
124124
cmd := exec.CommandContext(ctx, command[0], command[1:]...)
125125
cmd.Dir = dir
126126
cmd.Stderr = os.Stderr
127+
process.SetSysProcAttribute(cmd)
127128

128129
stdout, err := cmd.StdoutPipe()
129130
if err != nil {

modules/git/command.go

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ func (c *Command) Run(opts *RunOpts) error {
157157
"GIT_NO_REPLACE_OBJECTS=1",
158158
)
159159

160+
process.SetSysProcAttribute(cmd)
160161
cmd.Dir = opts.Dir
161162
cmd.Stdout = opts.Stdout
162163
cmd.Stderr = opts.Stderr

modules/markup/external/external.go

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
124124
cmd.Stdin = input
125125
}
126126
cmd.Stdout = output
127+
process.SetSysProcAttribute(cmd)
128+
127129
if err := cmd.Run(); err != nil {
128130
return fmt.Errorf("%s render run command %s %v failed: %v", p.Name(), commands[0], args, err)
129131
}

modules/process/manager_exec.go

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func (pm *Manager) ExecDirEnvStdIn(ctx context.Context, timeout time.Duration, d
5858
if stdIn != nil {
5959
cmd.Stdin = stdIn
6060
}
61+
SetSysProcAttribute(cmd)
6162

6263
if err := cmd.Start(); err != nil {
6364
return "", "", err

modules/process/manager_unix.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !windows
6+
7+
package process
8+
9+
import (
10+
"os/exec"
11+
"syscall"
12+
)
13+
14+
// SetSysProcAttribute sets the common SysProcAttrs for commands
15+
func SetSysProcAttribute(cmd *exec.Cmd) {
16+
// When Gitea runs SubProcessA -> SubProcessB and SubProcessA gets killed by context timeout, use setpgid to make sure the sub processes can be reaped instead of leaving defunct(zombie) processes.
17+
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
18+
}

modules/process/manager_windows.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build windows
6+
7+
package process
8+
9+
import (
10+
"os/exec"
11+
)
12+
13+
// SetSysProcAttribute sets the common SysProcAttrs for commands
14+
func SetSysProcAttribute(cmd *exec.Cmd) {
15+
// Do nothing
16+
}

modules/ssh/ssh.go

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ func sessionHandler(session ssh.Session) {
102102
}
103103
defer stdin.Close()
104104

105+
process.SetSysProcAttribute(cmd)
106+
105107
wg := &sync.WaitGroup{}
106108
wg.Add(2)
107109

services/mailer/mailer.go

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
281281
if err != nil {
282282
return err
283283
}
284+
process.SetSysProcAttribute(cmd)
284285

285286
if err = cmd.Start(); err != nil {
286287
_ = pipe.Close()

0 commit comments

Comments
 (0)