@@ -268,6 +268,8 @@ type Machine struct {
268268 startOnce sync.Once
269269 // exitCh is a channel which gets closed when the VMM exits
270270 exitCh chan struct {}
271+ // shutdownCh is a channel which gets closed when the VM is shutdown
272+ shutdownCh chan struct {}
271273 // fatalErr records an error that either stops or prevent starting the VMM
272274 fatalErr error
273275
@@ -360,8 +362,9 @@ func configureBuilder(builder VMCommandBuilder, cfg Config) VMCommandBuilder {
360362// provided Config.
361363func NewMachine (ctx context.Context , cfg Config , opts ... Opt ) (* Machine , error ) {
362364 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 {}),
365368 }
366369
367370 if cfg .VMID == "" {
@@ -460,6 +463,9 @@ func (m *Machine) Start(ctx context.Context) error {
460463// Shutdown requests a clean shutdown of the VM by sending CtrlAltDelete on the virtual keyboard
461464func (m * Machine ) Shutdown (ctx context.Context ) error {
462465 m .logger .Debug ("Called machine.Shutdown()" )
466+
467+ close (m .shutdownCh )
468+
463469 if runtime .GOARCH != "arm64" {
464470 return m .sendCtrlAltDel (ctx )
465471 } else {
@@ -588,6 +594,15 @@ func (m *Machine) startVMM(ctx context.Context) error {
588594 errCh := make (chan error )
589595 go func () {
590596 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+
591606 if waitErr != nil {
592607 m .logger .Warnf ("firecracker exited: %s" , waitErr .Error ())
593608 } else {
@@ -606,7 +621,6 @@ func (m *Machine) startVMM(ctx context.Context) error {
606621 // second one never ends as it tries to read from empty channel.
607622 close (errCh )
608623 close (m .cleanupCh )
609-
610624 }()
611625
612626 m .setupSignals ()
0 commit comments