mirror of
https://github.com/seriousm4x/UpSnap.git
synced 2026-07-29 08:52:51 -04:00
fix: use SIGTERM, then SIGKILL to avoid zombies #266
This commit is contained in:
@@ -31,9 +31,10 @@ func ShutdownDevice(device *models.Record) error {
|
||||
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(ctx, shell, shell_arg, shutdown_cmd)
|
||||
SetProcessAttributes(cmd)
|
||||
logger.Debug.Println(cmd)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
@@ -56,7 +57,6 @@ func ShutdownDevice(device *models.Record) error {
|
||||
if err := KillProcess(cmd.Process); err != nil {
|
||||
logger.Error.Println(err)
|
||||
}
|
||||
cancel()
|
||||
return fmt.Errorf("%s not offline after 2 minutes", device.GetString("name"))
|
||||
}
|
||||
isOnline := PingDevice(device)
|
||||
@@ -64,7 +64,6 @@ func ShutdownDevice(device *models.Record) error {
|
||||
if err := KillProcess(cmd.Process); err != nil {
|
||||
logger.Error.Println(err)
|
||||
}
|
||||
cancel()
|
||||
return nil
|
||||
}
|
||||
case err := <-done:
|
||||
@@ -72,7 +71,6 @@ func ShutdownDevice(device *models.Record) error {
|
||||
if err := KillProcess(cmd.Process); err != nil {
|
||||
logger.Error.Println(err)
|
||||
}
|
||||
cancel()
|
||||
return fmt.Errorf("%s", stderr.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/seriousm4x/upsnap/logger"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Set platform specifiy custom process attributes
|
||||
@@ -16,10 +15,18 @@ func SetProcessAttributes(cmd *exec.Cmd) {
|
||||
|
||||
// Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process.
|
||||
func KillProcess(process *os.Process) error {
|
||||
logger.Warning.Println("Your shutdown cmd didn't finish in 2 minutes. It will be killed.")
|
||||
pgid, err := unix.Getpgid(process.Pid)
|
||||
logger.Debug.Println(pgid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return unix.Kill(-pgid, unix.SIGKILL)
|
||||
|
||||
err = unix.Kill(-pgid, unix.SIGTERM)
|
||||
if err != nil {
|
||||
return unix.Kill(-pgid, unix.SIGKILL)
|
||||
}
|
||||
|
||||
_, err = process.Wait()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//go:build !linux
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package networking
|
||||
|
||||
@@ -12,8 +13,5 @@ func SetProcessAttributes(cmd *exec.Cmd) {}
|
||||
|
||||
// Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process.
|
||||
func KillProcess(process *os.Process) error {
|
||||
if err := process.Kill(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return windows.GenerateConsoleCtrlEvent(windows.CTRL_BREAK_EVENT, uint32(process.Pid))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user