@@ -268,6 +268,8 @@ type Machine struct {
268
268
startOnce sync.Once
269
269
// exitCh is a channel which gets closed when the VMM exits
270
270
exitCh chan struct {}
271
+ // shutdownCh is a channel which gets closed when the VM is shutdown
272
+ shutdownCh chan struct {}
271
273
// fatalErr records an error that either stops or prevent starting the VMM
272
274
fatalErr error
273
275
@@ -360,8 +362,9 @@ func configureBuilder(builder VMCommandBuilder, cfg Config) VMCommandBuilder {
360
362
// provided Config.
361
363
func NewMachine (ctx context.Context , cfg Config , opts ... Opt ) (* Machine , error ) {
362
364
m := & Machine {
363
- exitCh : make (chan struct {}),
364
- cleanupCh : make (chan struct {}),
365
+ exitCh : make (chan struct {}),
366
+ shutdownCh : make (chan struct {}),
367
+ cleanupCh : make (chan struct {}),
365
368
}
366
369
367
370
if cfg .VMID == "" {
@@ -460,6 +463,9 @@ func (m *Machine) Start(ctx context.Context) error {
460
463
// Shutdown requests a clean shutdown of the VM by sending CtrlAltDelete on the virtual keyboard
461
464
func (m * Machine ) Shutdown (ctx context.Context ) error {
462
465
m .logger .Debug ("Called machine.Shutdown()" )
466
+
467
+ close (m .shutdownCh )
468
+
463
469
if runtime .GOARCH != "arm64" {
464
470
return m .sendCtrlAltDel (ctx )
465
471
} else {
@@ -588,6 +594,15 @@ func (m *Machine) startVMM(ctx context.Context) error {
588
594
errCh := make (chan error )
589
595
go func () {
590
596
waitErr := m .cmd .Wait ()
597
+
598
+ // If using daemonized jailer and parent exits cleanly,
599
+ // this is expected behavior. Don't treat it as an error.
600
+ // We instead wait for closure of shutdownCh from m.Shutdown().
601
+ if m .Cfg .JailerCfg != nil && m .Cfg .JailerCfg .Daemonize && waitErr == nil {
602
+ m .logger .Debugf ("jailer parent exited (expected for daemonized mode)" )
603
+ <- m .shutdownCh
604
+ }
605
+
591
606
if waitErr != nil {
592
607
m .logger .Warnf ("firecracker exited: %s" , waitErr .Error ())
593
608
} else {
@@ -606,7 +621,6 @@ func (m *Machine) startVMM(ctx context.Context) error {
606
621
// second one never ends as it tries to read from empty channel.
607
622
close (errCh )
608
623
close (m .cleanupCh )
609
-
610
624
}()
611
625
612
626
m .setupSignals ()
0 commit comments