mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-21 07:47:52 +00:00
Merge pull request #29460 from RudraDudhat2509/fix/hyperv-vsock-ready-timeout
hyperv: add timeout to vsock ready wait
This commit is contained in:
commit
f63cf24b00
1 changed files with 27 additions and 2 deletions
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/go-winio"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -19,6 +20,17 @@ import (
|
|||
|
||||
var ErrVSockRegistryEntryExists = errors.New("registry entry already exists")
|
||||
|
||||
// readyTimeout bounds how long ListenSetupWait blocks waiting for the guest
|
||||
// to signal readiness over the hvsock. Without it, a guest that stays alive
|
||||
// but never connects (stuck boot, corrupted image, ignition hang) hangs the
|
||||
// calling `podman machine init`/`start` command forever: sockets.
|
||||
// ListenAndWaitOnSocket, which this waits on, has no timeout of its own,
|
||||
// confirmed by testing it directly against a real, unconnected net.Listener.
|
||||
// 10 real successful `podman machine init --now` runs from Podman's own
|
||||
// Hyper-V CI clustered between 15.8s and 19.4s, so 30s is headroom over a
|
||||
// normal healthy boot without leaving a stuck wait hanging for minutes.
|
||||
const readyTimeout = 30 * time.Second
|
||||
|
||||
const (
|
||||
// HvsockMachineName is the string identifier for the machine name in a registry entry
|
||||
HvsockMachineName = "MachineName"
|
||||
|
|
@ -308,7 +320,7 @@ func (hv *HVSockRegistryEntry) Listener() (net.Listener, 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
|
||||
// notification on the vsock, or times out after readyTimeout.
|
||||
func (hv *HVSockRegistryEntry) ListenSetupWait() (func() error, io.Closer, error) {
|
||||
listener, err := hv.Listener()
|
||||
if err != nil {
|
||||
|
|
@ -318,10 +330,23 @@ func (hv *HVSockRegistryEntry) ListenSetupWait() (func() error, io.Closer, error
|
|||
errChan := make(chan error)
|
||||
go sockets.ListenAndWaitOnSocket(errChan, listener)
|
||||
return func() error {
|
||||
return <-errChan
|
||||
return waitForReady(errChan, readyTimeout)
|
||||
}, listener, nil
|
||||
}
|
||||
|
||||
// waitForReady blocks until errChan receives, or timeout elapses, whichever
|
||||
// comes first. Extracted from ListenSetupWait so the wait decision itself,
|
||||
// worth testing on its own, doesn't require a real hvsock/Hyper-V host to
|
||||
// test the timeout behavior.
|
||||
func waitForReady(errChan <-chan error, timeout time.Duration) error {
|
||||
select {
|
||||
case err := <-errChan:
|
||||
return err
|
||||
case <-time.After(timeout):
|
||||
return fmt.Errorf("timed out after %s waiting for the VM to become ready", timeout)
|
||||
}
|
||||
}
|
||||
|
||||
// loadAllHVSockRegistryEntries loads HVSock registry entries, filtered by purpose and optionally limited by size.
|
||||
// If limit is -1, it returns all matching entries. Otherwise, it returns up to 'limit' entries.
|
||||
func loadHVSockRegistryEntries(purpose HVSockPurpose, limit int) ([]*HVSockRegistryEntry, error) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue