mirror of
https://github.com/containers/podman.git
synced 2025-06-22 09:58:10 +08:00
machine applehv: create better error on start failure
If gvproxy or vfkit exit we can error right away, so while we wait for the socket to get ready we also keep checking the process status with wait4() and WNOHANG so it does not block forever. This is completely untested as I do not have acces to apple machine. Signed-off-by: Paul Holzinger <pholzing@redhat.com> <MH: Added no new tests needed to pass CI> [NO NEW TESTS NEEDED] Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:

committed by
Matt Heon

parent
ee5f582fbc
commit
48cf44f233
@ -4,6 +4,7 @@
|
||||
package applehv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -669,10 +670,37 @@ func (m *MacMachine) Start(name string, opts machine.StartOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = <-readyChan
|
||||
processErrChan := make(chan error)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go func() {
|
||||
defer close(processErrChan)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
if err := checkProcessRunning("vfkit", cmd.Process.Pid); err != nil {
|
||||
processErrChan <- err
|
||||
return
|
||||
}
|
||||
// lets poll status every half second
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
|
||||
// wait for either socket or to be ready or process to have exited
|
||||
select {
|
||||
case err := <-processErrChan:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case err := <-readyChan:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Debug("ready notification received")
|
||||
machine.WaitAPIAndPrintInfo(
|
||||
@ -902,6 +930,10 @@ func (m *MacMachine) startHostNetworking() (string, machine.APIForwardingState,
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if err := checkProcessRunning("gvproxy", c.Process.Pid); err != nil {
|
||||
// gvproxy is no longer running
|
||||
return "", 0, err
|
||||
}
|
||||
logrus.Debugf("gvproxy unixgram socket %q not found: %v", m.GvProxySock.GetPath(), err)
|
||||
// Sleep for 1/2 second
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
@ -914,6 +946,21 @@ func (m *MacMachine) startHostNetworking() (string, machine.APIForwardingState,
|
||||
return forwardSock, state, nil
|
||||
}
|
||||
|
||||
// checkProcessRunning checks non blocking if the pid exited
|
||||
// returns nil if process is running otherwise an error if not
|
||||
func checkProcessRunning(processName string, pid int) error {
|
||||
var status syscall.WaitStatus
|
||||
pid, err := syscall.Wait4(pid, &status, syscall.WNOHANG, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read %s process status: %w", processName, err)
|
||||
}
|
||||
if pid > 0 {
|
||||
// child exited
|
||||
return fmt.Errorf("%s exited unexpectedly with exit code %d", processName, status.ExitStatus())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MacMachine) setupAPIForwarding(cmd gvproxy.GvproxyCommand) (gvproxy.GvproxyCommand, string, machine.APIForwardingState) {
|
||||
socket, err := m.forwardSocketPath()
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user