Skip to content

Commit ed6ff32

Browse files
authored
Merge pull request #666 from adamthomason/fix/startvmm-jailer-race-condition
Fix race condition with daemonized jailer in startVMM
2 parents 77c9459 + 9e975a7 commit ed6ff32

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

machine.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
361363
func 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
461464
func (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

Comments
 (0)