@@ -433,6 +433,17 @@ async def on_domain_shutdown(self, _event, **_kwargs):
433433 """Do auto cleanup if enabled"""
434434 await self ._auto_cleanup ()
435435
436+ @qubes .events .handler ("domain-remove-from-disk" )
437+ async def on_domain_delete (self , _event , ** _kwargs ) -> None :
438+ """
439+ On volume removal, remove preloaded disposable from ``preload-dispvm``
440+ feature in disposable template. If the feature is still here, it means
441+ the ``domain-shutdown`` cleanup was bypassed, possibly by improper
442+ shutdown, which can happen when a disposable is running, qubesd stops
443+ and system reboots.
444+ """
445+ self ._preload_cleanup ()
446+
436447 @qubes .events .handler ("property-pre-reset:template" )
437448 def on_property_pre_reset_template (self , event , name , oldvalue = None ):
438449 """Forbid deleting template of VM""" # pylint: disable=unused-argument
@@ -612,18 +623,26 @@ def use_preload(self):
612623 appvm .fire_event_async ("domain-preload-dispvm-used" , dispvm = self )
613624 )
614625
626+ def _preload_cleanup (self ):
627+ """Cleanup preload from list"""
628+ if self .name in self .template .get_feat_preload ():
629+ self .log .info ("Automatic cleanup removes qube from preload list" )
630+ self .template .remove_preload_from_list ([self .name ])
631+
615632 async def _bare_cleanup (self ):
616633 """Cleanup bare DispVM objects."""
617634 if self in self .app .domains :
618635 del self .app .domains [self ]
619636 await self .remove_from_disk ()
620637 self .app .save ()
621638
622- def _preload_cleanup (self ):
623- """Cleanup preload from list"""
624- if self .name in self .template .get_feat_preload ():
625- self .log .info ("Automatic cleanup removes qube from preload list" )
626- self .template .remove_preload_from_list ([self .name ])
639+ async def _auto_cleanup (self ):
640+ """Do auto cleanup if enabled"""
641+ if not self .auto_cleanup :
642+ return
643+ self ._preload_cleanup ()
644+ if self in self .app .domains :
645+ await self ._bare_cleanup ()
627646
628647 async def cleanup (self ):
629648 """Clean up after the DispVM
@@ -633,20 +652,14 @@ async def cleanup(self):
633652 """
634653 if self not in self .app .domains :
635654 return
655+ running = True
636656 try :
637657 await self .kill ()
638658 except qubes .exc .QubesVMNotStartedError :
639- pass
640- # This will be done automatically if event 'domain-shutdown' is
641- # triggered and 'auto_cleanup' evaluates to 'True'.
642- if not self .auto_cleanup :
643- self ._preload_cleanup ()
644- if self in self .app .domains :
645- await self ._bare_cleanup ()
646-
647- async def _auto_cleanup (self ):
648- """Do auto cleanup if enabled"""
649- if self .auto_cleanup :
659+ running = False
660+ # Full cleanup will be done automatically if event 'domain-shutdown' is
661+ # triggered and "auto_cleanup=True".
662+ if not running or not self .auto_cleanup :
650663 self ._preload_cleanup ()
651664 if self in self .app .domains :
652665 await self ._bare_cleanup ()
0 commit comments