@@ -636,7 +636,8 @@ func (s *service) mountDrives(requestCtx context.Context) error {
636
636
637
637
// StopVM will shutdown the VMM. Unlike Shutdown, this method is exposed to containerd clients.
638
638
// If the VM has not been created yet and the timeout is hit waiting for it to exist, an error will be returned
639
- // but the shim will continue to shutdown.
639
+ // but the shim will continue to shutdown. Similarly if we detect that the VM is in pause state, then
640
+ // we are unable to communicate to the in-VM agent. In this case, we do a forceful shutdown.
640
641
func (s * service ) StopVM (requestCtx context.Context , request * proto.StopVMRequest ) (_ * empty.Empty , err error ) {
641
642
defer logPanicAndDie (s .logger )
642
643
s .logger .WithFields (logrus.Fields {"timeout_seconds" : request .TimeoutSeconds }).Debug ("StopVM" )
@@ -646,6 +647,20 @@ func (s *service) StopVM(requestCtx context.Context, request *proto.StopVMReques
646
647
timeout = time .Duration (request .TimeoutSeconds ) * time .Second
647
648
}
648
649
650
+ info , err := s .machine .DescribeInstanceInfo (requestCtx )
651
+ if err != nil {
652
+ return nil , errors .Wrapf (err , "failed to get instance info %v" , info )
653
+ }
654
+
655
+ if * info .State == models .InstanceInfoStatePaused {
656
+ s .logger .Debug ("Instance is in Paused state, force shutdown in progress" )
657
+ err = s .jailer .Stop (true )
658
+ if err != nil {
659
+ return nil , errors .Wrap (err , "failed to stop VM in paused State" )
660
+ }
661
+ return & empty.Empty {}, nil
662
+ }
663
+
649
664
err = s .waitVMReady ()
650
665
if err != nil {
651
666
return nil , err
0 commit comments