@@ -60,7 +60,8 @@ type HostAgent struct {
6060 portForwarder * portForwarder // legacy SSH port forwarder
6161 grpcPortForwarder * portfwd.Forwarder
6262
63- onClose []func () error // LIFO
63+ onClose []func () error // LIFO
64+ onCloseMu sync.Mutex
6465
6566 driver driver.Driver
6667 signalCh chan os.Signal
@@ -460,26 +461,19 @@ func (a *HostAgent) startRoutinesAndWait(ctx context.Context, errCh <-chan error
460461 stRunning .Running = true
461462 a .emitEvent (ctx , events.Event {Status : stRunning })
462463 }()
463- for {
464- select {
465- case driverErr := <- errCh :
466- logrus .Infof ("Driver stopped due to error: %q" , driverErr )
467- cancelHA ()
468- if closeErr := a .close (); closeErr != nil {
469- logrus .WithError (closeErr ).Warn ("an error during shutting down the host agent" )
470- }
471- err := a .driver .Stop (ctx )
472- return err
473- case sig := <- a .signalCh :
474- logrus .Infof ("Received %s, shutting down the host agent" , osutil .SignalName (sig ))
475- cancelHA ()
476- if closeErr := a .close (); closeErr != nil {
477- logrus .WithError (closeErr ).Warn ("an error during shutting down the host agent" )
478- }
479- err := a .driver .Stop (ctx )
480- return err
481- }
482- }
464+ // wait for either the driver to stop or a signal to shut down
465+ select {
466+ case driverErr := <- errCh :
467+ logrus .Infof ("Driver stopped due to error: %q" , driverErr )
468+ case sig := <- a .signalCh :
469+ logrus .Infof ("Received %s, shutting down the host agent" , osutil .SignalName (sig ))
470+ }
471+ // close the host agent routines before cancelling the context
472+ if closeErr := a .close (); closeErr != nil {
473+ logrus .WithError (closeErr ).Warn ("an error during shutting down the host agent" )
474+ }
475+ cancelHA ()
476+ return a .driver .Stop (ctx )
483477}
484478
485479func (a * HostAgent ) Info (_ context.Context ) (* hostagentapi.Info , error ) {
@@ -500,7 +494,7 @@ func (a *HostAgent) startHostAgentRoutines(ctx context.Context) error {
500494 }
501495 logrus .Info (msg )
502496 }
503- a .onClose = append ( a . onClose , func () error {
497+ a .cleanUp ( func () error {
504498 logrus .Debugf ("shutting down the SSH master" )
505499 if exitMasterErr := ssh .ExitMaster (a .instSSHAddress , a .sshLocalPort , a .sshConfig ); exitMasterErr != nil {
506500 logrus .WithError (exitMasterErr ).Warn ("failed to exit SSH master" )
@@ -529,7 +523,7 @@ sudo chown -R "${USER}" /run/host-services`
529523 if err != nil {
530524 errs = append (errs , err )
531525 }
532- a .onClose = append ( a . onClose , func () error {
526+ a .cleanUp ( func () error {
533527 var unmountErrs []error
534528 for _ , m := range mounts {
535529 if unmountErr := m .close (); unmountErr != nil {
@@ -540,7 +534,7 @@ sudo chown -R "${USER}" /run/host-services`
540534 })
541535 }
542536 if len (a .instConfig .AdditionalDisks ) > 0 {
543- a .onClose = append ( a . onClose , func () error {
537+ a .cleanUp ( func () error {
544538 var unlockErrs []error
545539 for _ , d := range a .instConfig .AdditionalDisks {
546540 disk , inspectErr := store .InspectDisk (d .Name )
@@ -599,7 +593,7 @@ sudo chown -R "${USER}" /run/host-services`
599593 errs = append (errs , err )
600594 }
601595 }
602- a .onClose = append ( a . onClose , func () error {
596+ a .cleanUp ( func () error {
603597 var rmErrs []error
604598 for _ , rule := range a .instConfig .CopyToHost {
605599 if rule .DeleteOnStop {
@@ -614,7 +608,17 @@ sudo chown -R "${USER}" /run/host-services`
614608 return errors .Join (errs ... )
615609}
616610
611+ // cleanUp registers a cleanup function to be called when the host agent is stopped.
612+ // The cleanup functions are called before the context is cancelled, in the reverse order of their registration.
613+ func (a * HostAgent ) cleanUp (fn func () error ) {
614+ a .onCloseMu .Lock ()
615+ defer a .onCloseMu .Unlock ()
616+ a .onClose = append (a .onClose , fn )
617+ }
618+
617619func (a * HostAgent ) close () error {
620+ a .onCloseMu .Lock ()
621+ defer a .onCloseMu .Unlock ()
618622 logrus .Infof ("Shutting down the host agent" )
619623 var errs []error
620624 for i := len (a .onClose ) - 1 ; i >= 0 ; i -- {
@@ -643,7 +647,7 @@ func (a *HostAgent) watchGuestAgentEvents(ctx context.Context) {
643647 localUnix := filepath .Join (a .instDir , filenames .GuestAgentSock )
644648 remoteUnix := "/run/lima-guestagent.sock"
645649
646- a .onClose = append ( a . onClose , func () error {
650+ a .cleanUp ( func () error {
647651 logrus .Debugf ("Stop forwarding unix sockets" )
648652 var errs []error
649653 for _ , rule := range a .instConfig .PortForwards {
@@ -677,6 +681,9 @@ func (a *HostAgent) watchGuestAgentEvents(ctx context.Context) {
677681 }
678682 }()
679683
684+ // ensure close before ctx is cancelled
685+ a .cleanUp (a .grpcPortForwarder .Close )
686+
680687 for {
681688 if a .client == nil || ! isGuestAgentSocketAccessible (ctx , a .client ) {
682689 if a .driver .ForwardGuestAgent () {
@@ -809,7 +816,6 @@ func (a *HostAgent) processGuestAgentEvents(ctx context.Context, client *guestag
809816 a .grpcPortForwarder .OnEvent (ctx , client , ev )
810817 }
811818 }
812- defer a .grpcPortForwarder .Close ()
813819
814820 if err := client .Events (ctx , onEvent ); err != nil {
815821 if status .Code (err ) == codes .Canceled {
0 commit comments