@@ -522,6 +522,36 @@ def __init__(self):
522522 )
523523 self .devices_cache = collections .defaultdict (dict )
524524
525+ async def _auto_attach_devices (self , vm ):
526+ # pylint: disable=unused-argument
527+ to_attach = {}
528+ assignments = get_assigned_devices (vm .devices ["usb" ])
529+ # the most specific assignments first
530+ for assignment in reversed (sorted (assignments )):
531+ for device in assignment .devices :
532+ if isinstance (device , qubes .device_protocol .UnknownDevice ):
533+ continue
534+ if device .attachment :
535+ continue
536+ if not assignment .matches (device ):
537+ print (
538+ "Unrecognized identity, skipping attachment of device "
539+ f"from the port { assignment } " ,
540+ file = sys .stderr ,
541+ )
542+ continue
543+ # chose first assignment (the most specific) and ignore rest
544+ if device not in to_attach :
545+ # make it unique
546+ to_attach [device ] = assignment .clone (device = device )
547+ in_progress = set ()
548+ for assignment in to_attach .values ():
549+ in_progress .add (
550+ asyncio .ensure_future (self .attach_and_notify (vm , assignment ))
551+ )
552+ if in_progress :
553+ await asyncio .wait (in_progress )
554+
525555 @qubes .ext .handler ("domain-init" , "domain-load" )
526556 def on_domain_init_load (self , vm , event ):
527557 """Initialize watching for changes"""
@@ -743,41 +773,19 @@ async def on_device_assign_usb(self, vm, event, device, options):
743773
744774 @qubes .ext .handler ("domain-start" )
745775 async def on_domain_start (self , vm , _event , ** _kwargs ):
746- # pylint: disable=unused-argument
747- to_attach = {}
748- assignments = get_assigned_devices (vm .devices ["usb" ])
749- # the most specific assignments first
750- for assignment in reversed (sorted (assignments )):
751- for device in assignment .devices :
752- if isinstance (device , qubes .device_protocol .UnknownDevice ):
753- continue
754- if device .attachment :
755- continue
756- if not assignment .matches (device ):
757- print (
758- "Unrecognized identity, skipping attachment of device "
759- f"from the port { assignment } " ,
760- file = sys .stderr ,
761- )
762- continue
763- # chose first assignment (the most specific) and ignore rest
764- if device not in to_attach :
765- # make it unique
766- to_attach [device ] = assignment .clone (device = device )
767- in_progress = set ()
768- for assignment in to_attach .values ():
769- in_progress .add (
770- asyncio .ensure_future (self .attach_and_notify (vm , assignment ))
771- )
772- if in_progress :
773- await asyncio .wait (in_progress )
776+ await self ._auto_attach_devices (vm )
774777
775778 @qubes .ext .handler ("domain-shutdown" )
776779 async def on_domain_shutdown (self , vm , _event , ** _kwargs ):
777780 # pylint: disable=unused-argument
778781 vm .fire_event ("device-list-change:usb" )
779782 utils .device_list_change (self , {}, vm , None , USBDevice )
780783
784+ @qubes .ext .handler ("domain-unpaused" )
785+ async on_domain_unpaused (self , vm , _event , ** _kwargs ):
786+ loop = asyncio .get_running_loop ()
787+ asyncio .run_coroutine_threadsafe (self ._auto_attach_devices (vm ), loop )
788+
781789 @qubes .ext .handler ("qubes-close" , system = True )
782790 def on_qubes_close (self , app , event ):
783791 # pylint: disable=unused-argument
0 commit comments