🐛 修复 WebSSH 连接断开后遗留僵尸进程

This commit is contained in:
naiba 2021-09-30 12:01:01 +08:00
parent a25a1b128d
commit 7422de1269
4 changed files with 49 additions and 11 deletions

View File

@ -330,6 +330,7 @@ func handleCommandTask(task *pb.Task, result *pb.TaskResult) {
result.Data = string(output) result.Data = string(output)
result.Successful = true result.Successful = true
} }
pg.Dispose()
result.Delay = float32(time.Since(startedAt).Seconds()) result.Delay = float32(time.Since(startedAt).Seconds())
} }
@ -365,9 +366,9 @@ func handleTerminalTask(task *pb.Task) {
} }
defer func() { defer func() {
tty.Close() err := tty.Close()
conn.Close() conn.Close()
println("terminal exit", terminal.Session) println("terminal exit", terminal.Session, err)
}() }()
println("terminal init", terminal.Session) println("terminal init", terminal.Session)

View File

@ -64,7 +64,9 @@ func GetHost() *model.Host {
swapMemTotal = mv.SwapTotal swapMemTotal = mv.SwapTotal
} }
cachedBootTime = time.Unix(int64(hi.BootTime), 0) if cachedBootTime.IsZero() {
cachedBootTime = time.Unix(int64(hi.BootTime), 0)
}
return &model.Host{ return &model.Host{
Platform: hi.OS, Platform: hi.OS,

View File

@ -1,9 +1,11 @@
//go:build !windows
// +build !windows // +build !windows
package processgroup package processgroup
import ( import (
"os/exec" "os/exec"
"sync"
"syscall" "syscall"
) )
@ -15,13 +17,34 @@ func NewProcessExitGroup() (ProcessExitGroup, error) {
return ProcessExitGroup{}, nil return ProcessExitGroup{}, nil
} }
func (g *ProcessExitGroup) Dispose() error { func (g *ProcessExitGroup) killChildProcess(c *exec.Cmd) error {
for _, c := range g.cmds { pgid, err := syscall.Getpgid(c.Process.Pid)
if err := syscall.Kill(-c.Process.Pid, syscall.SIGKILL); err != nil { if err != nil {
return err // Fall-back on error. Kill the main process only.
} c.Process.Kill()
} }
return nil // Kill the whole process group.
syscall.Kill(-pgid, syscall.SIGTERM)
return c.Wait()
}
func (g *ProcessExitGroup) Dispose() []error {
var errors []error
mutex := new(sync.Mutex)
wg := new(sync.WaitGroup)
wg.Add(len(g.cmds))
for _, c := range g.cmds {
go func(c *exec.Cmd) {
defer wg.Done()
if err := g.killChildProcess(c); err != nil {
mutex.Lock()
defer mutex.Unlock()
errors = append(errors, err)
}
}(c)
}
wg.Wait()
return errors
} }
func (g *ProcessExitGroup) AddProcess(cmd *exec.Cmd) error { func (g *ProcessExitGroup) AddProcess(cmd *exec.Cmd) error {

View File

@ -1,5 +1,5 @@
//go:build !windows //go:build !windows
//+build !windows // +build !windows
package pty package pty
@ -7,6 +7,7 @@ import (
"errors" "errors"
"os" "os"
"os/exec" "os/exec"
"syscall"
opty "github.com/creack/pty" opty "github.com/creack/pty"
) )
@ -53,9 +54,20 @@ func (pty *Pty) Setsize(cols, rows uint32) error {
}) })
} }
func (pty *Pty) killChildProcess(c *exec.Cmd) error {
pgid, err := syscall.Getpgid(c.Process.Pid)
if err != nil {
// Fall-back on error. Kill the main process only.
c.Process.Kill()
}
// Kill the whole process group.
syscall.Kill(-pgid, syscall.SIGTERM)
return c.Wait()
}
func (pty *Pty) Close() error { func (pty *Pty) Close() error {
if err := pty.tty.Close(); err != nil { if err := pty.tty.Close(); err != nil {
return err return err
} }
return pty.cmd.Process.Kill() return pty.killChildProcess(pty.cmd)
} }