mirror of
https://github.com/containers/podman.git
synced 2025-05-21 00:56:36 +08:00
Fix race conditions in hyperv readiness checking
- Listen before starting the vm - Fix a device race caused by lazy hv_vsock init by waiting on network manager [NO NEW TESTS NEEDED] Signed-off-by: Jason T. Greene <jason.greene@redhat.com>
This commit is contained in:
@ -215,8 +215,15 @@ func (h HyperVStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func(
|
||||
callbackFuncs.Add(rmIgnCallbackFunc)
|
||||
}
|
||||
|
||||
waitReady, listener, err := mc.HyperVHypervisor.ReadyVsock.ListenSetupWait()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = vm.Start()
|
||||
if err != nil {
|
||||
// cleanup the pending listener
|
||||
_ = listener.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@ -225,7 +232,7 @@ func (h HyperVStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func(
|
||||
}
|
||||
callbackFuncs.Add(startCallback)
|
||||
|
||||
return nil, mc.HyperVHypervisor.ReadyVsock.Listen, err
|
||||
return nil, waitReady, err
|
||||
}
|
||||
|
||||
// State is returns the state as a define.status. for hyperv, state differs from others because
|
||||
|
@ -5,6 +5,7 @@ package vsock
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
@ -258,21 +259,18 @@ func (hv *HVSockRegistryEntry) Listener() (net.Listener, error) {
|
||||
return listener, nil
|
||||
}
|
||||
|
||||
// Listen is used on the windows side to listen for anything to come
|
||||
// over the hvsock as a signal the vm is booted
|
||||
func (hv *HVSockRegistryEntry) Listen() error {
|
||||
// ListenSetupWait creates an hvsock on the windows side and returns
|
||||
// a wait function that, when called, blocks until it receives a ready
|
||||
// notification on the vsock
|
||||
func (hv *HVSockRegistryEntry) ListenSetupWait() (func() error, io.Closer, error) {
|
||||
listener, err := hv.Listener()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := listener.Close(); err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}()
|
||||
|
||||
errChan := make(chan error)
|
||||
go sockets.ListenAndWaitOnSocket(errChan, listener)
|
||||
|
||||
return <-errChan
|
||||
return func() error {
|
||||
return <-errChan
|
||||
}, listener, nil
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ func CreateReadyUnitFile(provider define.VMType, opts *ReadyUnitOpts) (string, e
|
||||
if opts == nil || opts.Port == 0 {
|
||||
return "", errors.New("no port provided for hyperv ready unit")
|
||||
}
|
||||
readyUnit.Add("Unit", "Requires", "sys-devices-virtual-net-vsock0.device")
|
||||
readyUnit.Add("Unit", "After", "systemd-user-sessions.service")
|
||||
readyUnit.Add("Unit", "After", "vsock-network.service")
|
||||
readyUnit.Add("Service", "ExecStart", fmt.Sprintf("/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:%d'", opts.Port))
|
||||
case define.WSLVirt: // WSL does not use ignition
|
||||
return "", nil
|
||||
|
Reference in New Issue
Block a user