From b2584a254b0522d01ff626cb5772cb460bc951e0 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 1 Jun 2022 17:21:46 +0100 Subject: [PATCH 1/9] Set Setpgid on child git processes 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 killed. Fix #19077 Signed-off-by: Andrew Thornton --- modules/git/command.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/git/command.go b/modules/git/command.go index 3dd12e421e409..b3266ce998731 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -13,6 +13,7 @@ import ( "os" "os/exec" "strings" + "syscall" "time" "unsafe" @@ -157,6 +158,7 @@ func (c *Command) Run(opts *RunOpts) error { "GIT_NO_REPLACE_OBJECTS=1", ) + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} cmd.Dir = opts.Dir cmd.Stdout = opts.Stdout cmd.Stderr = opts.Stderr From dfaff61d4a592e7a5e3c4a5abca72bb32baf8f21 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 1 Jun 2022 17:50:48 +0100 Subject: [PATCH 2/9] OK windows does not have this Signed-off-by: Andrew Thornton --- modules/git/command.go | 2 -- modules/git/command_unix.go | 16 ++++++++++++++++ modules/git/command_windows.go | 11 +++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 modules/git/command_unix.go create mode 100644 modules/git/command_windows.go diff --git a/modules/git/command.go b/modules/git/command.go index b3266ce998731..3dd12e421e409 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -13,7 +13,6 @@ import ( "os" "os/exec" "strings" - "syscall" "time" "unsafe" @@ -158,7 +157,6 @@ func (c *Command) Run(opts *RunOpts) error { "GIT_NO_REPLACE_OBJECTS=1", ) - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} cmd.Dir = opts.Dir cmd.Stdout = opts.Stdout cmd.Stderr = opts.Stderr diff --git a/modules/git/command_unix.go b/modules/git/command_unix.go new file mode 100644 index 0000000000000..d43aa1db0c50f --- /dev/null +++ b/modules/git/command_unix.go @@ -0,0 +1,16 @@ +// Copyright 2016 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// go:build !windows + +package git + +import ( + "os/exec" + "syscall" +) + +func setSysProcAttribute(cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} +} diff --git a/modules/git/command_windows.go b/modules/git/command_windows.go new file mode 100644 index 0000000000000..50ea2fb719712 --- /dev/null +++ b/modules/git/command_windows.go @@ -0,0 +1,11 @@ +// Copyright 2016 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// go:build windows + +package git + +func setSysProcAttribute(cmd *exec.Cmd) { + // Do nothing +} From e4b90e2f0d172e8647f41e80ee437a70c117dcc1 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 1 Jun 2022 19:04:58 +0100 Subject: [PATCH 3/9] oops Signed-off-by: Andrew Thornton --- modules/git/command.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/git/command.go b/modules/git/command.go index 3dd12e421e409..da0a1c1b9a046 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -157,6 +157,7 @@ func (c *Command) Run(opts *RunOpts) error { "GIT_NO_REPLACE_OBJECTS=1", ) + setSysProcAttribute(cmd) cmd.Dir = opts.Dir cmd.Stdout = opts.Stdout cmd.Stderr = opts.Stderr From d82bd9512c7ad9f31219ea650871470114e59400 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 1 Jun 2022 19:11:44 +0100 Subject: [PATCH 4/9] try to get the go:build to work properly Signed-off-by: Andrew Thornton --- modules/git/command_unix.go | 2 +- modules/git/command_windows.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/git/command_unix.go b/modules/git/command_unix.go index d43aa1db0c50f..a9e72796096db 100644 --- a/modules/git/command_unix.go +++ b/modules/git/command_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -// go:build !windows +//go:build !windows package git diff --git a/modules/git/command_windows.go b/modules/git/command_windows.go index 50ea2fb719712..344054524ec33 100644 --- a/modules/git/command_windows.go +++ b/modules/git/command_windows.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -// go:build windows +//go:build windows package git From 5b7f2019df30a8c00499ac249551b4aa5c482187 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 1 Jun 2022 19:30:28 +0100 Subject: [PATCH 5/9] Update modules/git/command_windows.go Co-authored-by: singuliere <35190819+singuliere@users.noreply.github.com> --- modules/git/command_windows.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/git/command_windows.go b/modules/git/command_windows.go index 344054524ec33..3c876ace5af8c 100644 --- a/modules/git/command_windows.go +++ b/modules/git/command_windows.go @@ -4,6 +4,10 @@ //go:build windows +import ( + "os/exec" +) + package git func setSysProcAttribute(cmd *exec.Cmd) { From 4dc3c63f62f4495376145c276d27a7cf2d0db81f Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Wed, 1 Jun 2022 14:46:48 -0400 Subject: [PATCH 6/9] Apply suggestions from code review --- modules/git/command_unix.go | 2 +- modules/git/command_windows.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/git/command_unix.go b/modules/git/command_unix.go index a9e72796096db..de81b76c9f27d 100644 --- a/modules/git/command_unix.go +++ b/modules/git/command_unix.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. diff --git a/modules/git/command_windows.go b/modules/git/command_windows.go index 3c876ace5af8c..c46463fbf139b 100644 --- a/modules/git/command_windows.go +++ b/modules/git/command_windows.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From 5d1941edde6eee666b02529338097a675dfa3813 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 1 Jun 2022 20:21:10 +0100 Subject: [PATCH 7/9] Apply suggestions from code review --- modules/git/command_windows.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/git/command_windows.go b/modules/git/command_windows.go index c46463fbf139b..3b2aecd8286aa 100644 --- a/modules/git/command_windows.go +++ b/modules/git/command_windows.go @@ -4,12 +4,12 @@ //go:build windows +package git + import ( "os/exec" ) -package git - func setSysProcAttribute(cmd *exec.Cmd) { // Do nothing } From fd060fa6a7f65ac915d75275aca7d8a281300a5c Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 2 Jun 2022 10:30:06 +0100 Subject: [PATCH 8/9] Extend to all other uses of CommandContext Signed-off-by: Andrew Thornton --- cmd/serv.go | 2 ++ modules/git/blame.go | 1 + modules/git/command.go | 2 +- modules/markup/external/external.go | 2 ++ modules/process/manager_exec.go | 1 + modules/{git/command_unix.go => process/manager_unix.go} | 5 +++-- .../{git/command_windows.go => process/manager_windows.go} | 5 +++-- modules/ssh/ssh.go | 2 ++ services/mailer/mailer.go | 1 + 9 files changed, 16 insertions(+), 5 deletions(-) rename modules/{git/command_unix.go => process/manager_unix.go} (69%) rename modules/{git/command_windows.go => process/manager_windows.go} (64%) diff --git a/cmd/serv.go b/cmd/serv.go index adfbc6024ca7c..6ba3e9de01ff9 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -24,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/pprof" "code.gitea.io/gitea/modules/private" + "code.gitea.io/gitea/modules/process" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/lfs" @@ -306,6 +307,7 @@ func runServ(c *cli.Context) error { } } + process.SetSysProcAttribute(gitcmd) gitcmd.Dir = setting.RepoRootPath gitcmd.Stdout = os.Stdout gitcmd.Stdin = os.Stdin diff --git a/modules/git/blame.go b/modules/git/blame.go index 40e3d4e885d29..1653ecbf854af 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -124,6 +124,7 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla cmd := exec.CommandContext(ctx, command[0], command[1:]...) cmd.Dir = dir cmd.Stderr = os.Stderr + process.SetSysProcAttribute(cmd) stdout, err := cmd.StdoutPipe() if err != nil { diff --git a/modules/git/command.go b/modules/git/command.go index da0a1c1b9a046..f6344dbfd1ae0 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -157,7 +157,7 @@ func (c *Command) Run(opts *RunOpts) error { "GIT_NO_REPLACE_OBJECTS=1", ) - setSysProcAttribute(cmd) + process.SetSysProcAttribute(cmd) cmd.Dir = opts.Dir cmd.Stdout = opts.Stdout cmd.Stderr = opts.Stderr diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go index 4fdd4315bc3e4..a587abcc3b6ff 100644 --- a/modules/markup/external/external.go +++ b/modules/markup/external/external.go @@ -124,6 +124,8 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io. cmd.Stdin = input } cmd.Stdout = output + process.SetSysProcAttribute(cmd) + if err := cmd.Run(); err != nil { return fmt.Errorf("%s render run command %s %v failed: %v", p.Name(), commands[0], args, err) } diff --git a/modules/process/manager_exec.go b/modules/process/manager_exec.go index 61ddae646f0e4..77e3d3193a9e7 100644 --- a/modules/process/manager_exec.go +++ b/modules/process/manager_exec.go @@ -58,6 +58,7 @@ func (pm *Manager) ExecDirEnvStdIn(ctx context.Context, timeout time.Duration, d if stdIn != nil { cmd.Stdin = stdIn } + SetSysProcAttribute(cmd) if err := cmd.Start(); err != nil { return "", "", err diff --git a/modules/git/command_unix.go b/modules/process/manager_unix.go similarity index 69% rename from modules/git/command_unix.go rename to modules/process/manager_unix.go index de81b76c9f27d..124ce510049f8 100644 --- a/modules/git/command_unix.go +++ b/modules/process/manager_unix.go @@ -4,13 +4,14 @@ //go:build !windows -package git +package process import ( "os/exec" "syscall" ) -func setSysProcAttribute(cmd *exec.Cmd) { +// SetSysProcAttribute sets the common SysProcAttrs for commands +func SetSysProcAttribute(cmd *exec.Cmd) { cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} } diff --git a/modules/git/command_windows.go b/modules/process/manager_windows.go similarity index 64% rename from modules/git/command_windows.go rename to modules/process/manager_windows.go index 3b2aecd8286aa..35f66d9fa5bcd 100644 --- a/modules/git/command_windows.go +++ b/modules/process/manager_windows.go @@ -4,12 +4,13 @@ //go:build windows -package git +package process import ( "os/exec" ) -func setSysProcAttribute(cmd *exec.Cmd) { +// SetSysProcAttribute sets the common SysProcAttrs for commands +func SetSysProcAttribute(cmd *exec.Cmd) { // Do nothing } diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index fe3561cefaa37..a240c013191ba 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -102,6 +102,8 @@ func sessionHandler(session ssh.Session) { } defer stdin.Close() + process.SetSysProcAttribute(cmd) + wg := &sync.WaitGroup{} wg.Add(2) diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index 3ca9b50fc6147..f4bc2ddc630cd 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -281,6 +281,7 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error { if err != nil { return err } + process.SetSysProcAttribute(cmd) if err = cmd.Start(); err != nil { _ = pipe.Close() From 44982950437bf054f86293ff4859255abf35e5e3 Mon Sep 17 00:00:00 2001 From: zeripath Date: Fri, 3 Jun 2022 14:28:07 +0100 Subject: [PATCH 9/9] Update modules/process/manager_unix.go Co-authored-by: wxiaoguang --- modules/process/manager_unix.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/process/manager_unix.go b/modules/process/manager_unix.go index 124ce510049f8..1e7c77fdbf951 100644 --- a/modules/process/manager_unix.go +++ b/modules/process/manager_unix.go @@ -13,5 +13,6 @@ import ( // SetSysProcAttribute sets the common SysProcAttrs for commands func SetSysProcAttribute(cmd *exec.Cmd) { + // 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. cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} }