Fixups for stopping gvproxy

Paul found logic errors in my earlier code for finding processes and
sending signals.  Some of the logic errors are associated with how
methods behave on different operating systems.  Created a darwin and
linux approach and a windows approach.

Signed-off-by: Brent Baude <bbaude@redhat.com>

[NO NEW TESTS NEEDED]
This commit is contained in:
Brent Baude
2023-08-22 15:56:00 -05:00
parent 7bd60867de
commit 9e680cbc63
3 changed files with 46 additions and 8 deletions

View File

@ -2,7 +2,6 @@ package machine
import (
"fmt"
"os"
"strconv"
"syscall"
"time"
@ -19,7 +18,7 @@ const (
func backoffForProcess(pid int) error {
sleepInterval := sleepTime
for i := 0; i < loops; i++ {
proxyProc, err := os.FindProcess(pid)
proxyProc, err := findProcess(pid)
if proxyProc == nil && err != nil {
// process is killed, gone
return nil //nolint: nilerr
@ -35,13 +34,16 @@ func backoffForProcess(pid int) error {
// process to not exist. if the sigterm does not end the process after an interval,
// then sigkill is sent. it also waits for the process to exit after the sigkill too.
func waitOnProcess(processID int) error {
proxyProc, err := os.FindProcess(processID)
proxyProc, err := findProcess(processID)
if err != nil {
return err
}
// Try to kill the pid with sigterm
if err := proxyProc.Signal(syscall.SIGTERM); err != nil {
if err == syscall.ESRCH {
return nil
}
return err
}
@ -50,14 +52,16 @@ func waitOnProcess(processID int) error {
}
// sigterm has not killed it yet, lets send a sigkill
proxyProc, err = os.FindProcess(processID)
proxyProc, err = findProcess(processID)
if proxyProc == nil && err != nil {
// process is killed, gone
return nil //nolint: nilerr
}
if err := proxyProc.Signal(syscall.SIGKILL); err != nil {
// lets assume it is dead in this case
return nil //nolint: nilerr
if err == syscall.ESRCH {
return nil
}
return err
}
return backoffForProcess(processID)
}
@ -72,8 +76,8 @@ func CleanupGVProxy(f VMFile) error {
if err != nil {
return fmt.Errorf("unable to convert pid to integer: %v", err)
}
if err := waitOnProcess(proxyPid); err == nil {
return nil
if err := waitOnProcess(proxyPid); err != nil {
return err
}
return f.Delete()
}

View File

@ -0,0 +1,24 @@
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
// +build darwin dragonfly freebsd linux netbsd openbsd
package machine
import (
"os"
"syscall"
)
func findProcess(pid int) (*os.Process, error) {
p, err := os.FindProcess(pid)
if err != nil {
return nil, err
}
// On unix, findprocess will always return a process even
// if the process is not found. you must send a 0 signal
// to the process to see if it is alive.
// https://pkg.go.dev/os#FindProcess
if err := p.Signal(syscall.Signal(0)); err != nil {
return nil, err
}
return p, nil
}

View File

@ -0,0 +1,10 @@
//go:build windows
// +build windows
package machine
import "os"
func findProcess(pid int) (*os.Process, error) {
return os.FindProcess(pid)
}