@@ -68,12 +68,18 @@ func init() {
6868}
6969
7070const (
71- defaultVsockPort = 10789
72- minVsockIOPort = uint32 (11000 )
73- firecrackerStartTimeout = 5 * time .Second
74- defaultStopVMTimeout = 5 * time .Second
75- defaultShutdownTimeout = 5 * time .Second
76- jailerStopTimeout = 3 * time .Second
71+ defaultVsockPort = 10789
72+ minVsockIOPort = uint32 (11000 )
73+
74+ // vmReadyTimeout is used to control the time all requests wait a Go channel (vmReady) before calling
75+ // Firecracker's API server. The channel is closed once the VM starts.
76+ vmReadyTimeout = 5 * time .Second
77+
78+ defaultCreateVMTimeout = 20 * time .Second
79+ defaultStopVMTimeout = 5 * time .Second
80+ defaultShutdownTimeout = 5 * time .Second
81+
82+ jailerStopTimeout = 3 * time .Second
7783
7884 // StartEventName is the topic published to when a VM starts
7985 StartEventName = "/firecracker-vm/start"
@@ -425,7 +431,7 @@ func (s *service) waitVMReady() error {
425431 select {
426432 case <- s .vmReady :
427433 return nil
428- case <- time .After (firecrackerStartTimeout ):
434+ case <- time .After (vmReadyTimeout ):
429435 return status .Error (codes .DeadlineExceeded , "timed out waiting for VM start" )
430436 }
431437}
@@ -435,14 +441,21 @@ func (s *service) waitVMReady() error {
435441func (s * service ) CreateVM (requestCtx context.Context , request * proto.CreateVMRequest ) (* proto.CreateVMResponse , error ) {
436442 defer logPanicAndDie (s .logger )
437443
444+ timeout := defaultCreateVMTimeout
445+ if request .TimeoutSeconds > 0 {
446+ timeout = time .Duration (request .TimeoutSeconds ) * time .Second
447+ }
448+ ctxWithTimeout , cancel := context .WithTimeout (requestCtx , timeout )
449+ defer cancel ()
450+
438451 var (
439452 err error
440453 createRan bool
441454 resp proto.CreateVMResponse
442455 )
443456
444457 s .vmStartOnce .Do (func () {
445- err = s .createVM (requestCtx , request )
458+ err = s .createVM (ctxWithTimeout , request )
446459 createRan = true
447460 })
448461
@@ -453,9 +466,13 @@ func (s *service) CreateVM(requestCtx context.Context, request *proto.CreateVMRe
453466 // If we failed to create the VM, we have no point in existing anymore, so shutdown
454467 if err != nil {
455468 s .shimCancel ()
456- err = errors .Wrap (err , "failed to create VM" )
457- s .logger .WithError (err ).Error ()
458- return nil , err
469+
470+ s .logger .WithError (err ).Error ("failed to create VM" )
471+
472+ if errors .Cause (err ) == context .DeadlineExceeded {
473+ return nil , status .Errorf (codes .DeadlineExceeded , "VM %q didn't start within %s: %s" , request .VMID , timeout , err )
474+ }
475+ return nil , errors .Wrap (err , "failed to create VM" )
459476 }
460477
461478 // creating the VM succeeded, setup monitors and publish events to celebrate
0 commit comments