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