diff --git a/pkg/machine/hyperv/stubber.go b/pkg/machine/hyperv/stubber.go index 97c5edb623..03838a9aee 100644 --- a/pkg/machine/hyperv/stubber.go +++ b/pkg/machine/hyperv/stubber.go @@ -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 diff --git a/pkg/machine/hyperv/vsock/vsock.go b/pkg/machine/hyperv/vsock/vsock.go index 8f488e2534..202faafb38 100644 --- a/pkg/machine/hyperv/vsock/vsock.go +++ b/pkg/machine/hyperv/vsock/vsock.go @@ -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 } diff --git a/pkg/machine/ignition/ready.go b/pkg/machine/ignition/ready.go index 42a50dcfda..68bb57577b 100644 --- a/pkg/machine/ignition/ready.go +++ b/pkg/machine/ignition/ready.go @@ -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