@@ -77,8 +77,8 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
7777
7878 - Full start: Preloaded disposable must only be interrupted
7979 (paused/suspended) or used after all basic services in it have been
80- started. Autostarted applications allows user interaction before the it
81- should, that is a bug .
80+ started. Failure to complete this step must remove the qube from the
81+ preload list .
8282
8383 - **Prevents accidental tampering**:
8484
@@ -92,12 +92,11 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
9292 GUI applications, that is a bug because features cannot be set before
9393 that event.
9494
95- - Preloaded qubes must be marked as used when prior to being
96- unpaused/resumed, even if it was not requested. The goal of
97- pause/suspend in case of preloaded disposables is mostly detecting
98- whether a qube was used or not, and not managing resource consumption;
99- thus, even with abundant system resources, they should not be
100- unpaused/resumed without being requested.
95+ - Preloaded qubes must be marked as used after being unpaused/resumed,
96+ even if it was not requested. The goal of pause/suspend in case of
97+ preloaded disposables is mostly detecting whether a qube was used or
98+ not, not managing resource consumption; thus, even with abundant system
99+ resources, they should not be unpaused/resumed without being requested.
101100
102101 **Stages**:
103102
@@ -114,14 +113,6 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
114113 applicable). Only in this phase, GUI applications treat the qube as any
115114 other unnamed disposable and the qube object is returned to the caller if
116115 requested.
117-
118- **Outstanding bugs**:
119-
120- - GUI applications set to autostart can appear on the screen and be
121- interactive for a brief moment before the qube is allowed to be used
122- followed by a sudden freeze.
123- - Can't interrupt qubes before the GUI session has started if the qube's
124- usage will require a GUI (GUI daemon cannot handle an interrupted qube).
125116 """
126117
127118 template = qubes .VMProperty (
@@ -328,37 +319,33 @@ async def on_domain_started_dispvm(
328319 """
329320 if not self .is_preload :
330321 return
331- # TODO: pause is late for autostarted GUI applications
332- # https://github.com/QubesOS/qubes-issues/issues/9907
333322 timeout = self .qrexec_timeout
334- gui = bool ( self . guivm and self . features . get ( "gui" , True ))
335- service = "qubes.WaitForSession "
336- if not gui :
337- service = "qubes.WaitForRunningSystem "
323+ # https://github.com/QubesOS/qubes-issues/issues/9964
324+ rpc = "qubes.WaitForRunningSystem "
325+ path = "/run/qubes-rpc:/usr/local/etc/qubes-rpc:/etc/qubes-rpc"
326+ service = '$(PATH="' + path + '" command -v ' + rpc + ") "
338327 try :
339328 self .log .info (
340- "Waiting '%s' with timeout of '%d' seconds" , service , timeout
329+ "Waiting for '%s' with timeout of '%d' seconds" ,
330+ service ,
331+ timeout ,
341332 )
342333 await asyncio .wait_for (
343- self .run_service_for_stdio (
334+ self .run (
344335 service ,
345- user = self .default_user ,
346336 stdout = subprocess .DEVNULL ,
347337 stderr = subprocess .DEVNULL ,
348338 ),
349339 timeout = timeout ,
350340 )
351341 except asyncio .TimeoutError :
352- # TODO: if pause occurs before the GUI session starts (on boot
353- # before login manager), results in an unusable GUI for the qube:
354- # https://github.com/QubesOS/qubes-issues/issues/9940
355342 raise qubes .exc .QubesException (
356- "Timed out Qrexec call to '%s' after '%d' seconds during "
357- "preload startup" % (service , timeout )
343+ "Timed out call to '%s' after '%d' seconds during preload "
344+ "startup" % (service , timeout )
358345 )
359346 except (subprocess .CalledProcessError , qubes .exc .QubesException ):
360347 raise qubes .exc .QubesException (
361- "Error on Qrexec call to '%s' during preload startup" % service
348+ "Error on call to '%s' during preload startup" % service
362349 )
363350
364351 if self .is_preload :
@@ -376,11 +363,11 @@ def on_domain_paused(
376363 if self .is_preload :
377364 self .log .info ("Paused preloaded qube" )
378365
379- @qubes .events .handler ("domain-pre- unpaused" )
380- def on_domain_pre_unpaused (
366+ @qubes .events .handler ("domain-unpaused" )
367+ def on_domain_unpaused (
381368 self , event , ** kwargs
382369 ): # pylint: disable=unused-argument
383- """Mark preloaded domains as used before being unpaused ."""
370+ """Mark preloaded disposables as used."""
384371 # Qube start triggers unpause via 'libvirt_domain.resume()'.
385372 if self .is_preload and self .is_fully_usable ():
386373 self .log .info ("Unpaused preloaded qube will be marked as used" )
@@ -490,7 +477,8 @@ async def from_appvm(cls, appvm, preload=False, **kwargs):
490477 # requesting the qube.
491478 appvm .remove_preload_from_list ([dispvm .name ])
492479 dispvm .features ["preload-dispvm-request" ] = True
493- tries , sleep = 1200 , 0.1
480+ sleep = 0.1
481+ tries = int (dispvm .qrexec_timeout * 1.2 / sleep )
494482 for _ in range (tries ):
495483 if dispvm .features .get (
496484 "preload-dispvm-skip-interrupt" , None
0 commit comments