diff --git a/pkg/machine/gvproxy.go b/pkg/machine/gvproxy.go index 8cc8f00443..f159b8266c 100644 --- a/pkg/machine/gvproxy.go +++ b/pkg/machine/gvproxy.go @@ -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() } diff --git a/pkg/machine/gvproxy_unix.go b/pkg/machine/gvproxy_unix.go new file mode 100644 index 0000000000..7168e09536 --- /dev/null +++ b/pkg/machine/gvproxy_unix.go @@ -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 +} diff --git a/pkg/machine/gvproxy_windows.go b/pkg/machine/gvproxy_windows.go new file mode 100644 index 0000000000..ee1f4b8be3 --- /dev/null +++ b/pkg/machine/gvproxy_windows.go @@ -0,0 +1,10 @@ +//go:build windows +// +build windows + +package machine + +import "os" + +func findProcess(pid int) (*os.Process, error) { + return os.FindProcess(pid) +}