Skip to content

Conversation

@ben-grande
Copy link
Contributor

  • Autostarted applications don't show when preloading; and
  • Preloaded qubes paused before the session will have a working GUI when
    the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907

@ben-grande
Copy link
Contributor Author

Before this is merged, let me know to update the documentation of the manpage and the DispVM class accordingly. Maybe I will merge this PR:

@ben-grande
Copy link
Contributor Author

ben-grande commented May 15, 2025

This is working because failing qubes.WaitForSession was just logging a warning, I changed it to raise QubesException because it is more correct.

https://github.com/QubesOS/qubes-core-admin/blob/b1d178670abea07cc1d3f51243fd3d18fb49d707/qubes/vm/dispvm.py#L354

https://github.com/QubesOS/qubes-core-admin/compare/d53d9604b026fa0fd7e5d7c4015996618f4651a9..b1d178670abea07cc1d3f51243fd3d18fb49d707

But now, qubes.WaitForSession can't be called there, only qubes.WaitForRunningSystem, which is okay even for the GUI qube as it doesn't connect before being used due to this PR.

Adding a check for qubes.WaitForSession after being marked as used doesn't make sense I believe, because, well, it adds a test but won't help with anything...


Note to self:

This requires changes in core-admin:

  • no qubes.WaitForSession
  • change domain-pre-unpaused to domain-unpaused

@ben-grande
Copy link
Contributor Author

I haven't checked if there is any impact of a super late connection, such as a preload that was paused for some hours and them it is unpaused and the GUID will try to connect, will have to check if the client responds.

try:
if "guivm" in self.enabled_services:
asyncio.ensure_future(
self.start_gui(vm, monitor_layout=monitor_layout)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I use force_stubdom=True? I haven't experimented with HVMs for this use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, force_stubdomain is only a debugging feature

@ben-grande
Copy link
Contributor Author

Rebased on top of:

ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request May 16, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 7, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
@ben-grande ben-grande force-pushed the late-preload branch 5 times, most recently from 4ed916b to 1cf336d Compare June 7, 2025 18:49
@marmarek
Copy link
Member

marmarek commented Jun 8, 2025

There is a merge conflict now...

ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 10, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
@marmarek
Copy link
Member

Oh, I see a bunch of related exceptions in .xsession-errors log:

/usr/lib/python3.13/site-packages/qubesadmin/tools/qvm_start_daemon.py:821> exception=TypeError('expected str, bytes or os.PathLike object, not int')>
Traceback (most recent call last):
  File "/usr/lib/python3.13/site-packages/qubesadmin/tools/qvm_start_daemon.py", line 840, in start_audio
    await self.start_audio_for_vm(vm)
  File "/usr/lib/python3.13/site-packages/qubesadmin/tools/qvm_start_daemon.py", line 793, in start_audio_for_vm
    await asyncio.create_subprocess_exec(*pacat_cmd)
  File "/usr/lib64/python3.13/asyncio/subprocess.py", line 224, in create_subprocess_exec
    transport, protocol = await loop.subprocess_exec(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
        stderr=stderr, **kwds)
        ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/asyncio/base_events.py", line 1788, in subprocess_exec
    transport = await self._make_subprocess_transport(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        protocol, popen_args, False, stdin, stdout, stderr,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        bufsize, **kwargs)
        ^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/asyncio/unix_events.py", line 213, in _make_subprocess_transport
    transp = _UnixSubprocessTransport(self, protocol, args, shell,
                                    stdin, stdout, stderr, bufsize,
                                    waiter=waiter, extra=extra,
                                    **kwargs)
  File "/usr/lib64/python3.13/asyncio/base_subprocess.py", line 39, in __init__
    self._start(args=args, shell=shell, stdin=stdin, stdout=stdout,
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                stderr=stderr, bufsize=bufsize, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/asyncio/unix_events.py", line 855, in _start
    self._proc = subprocess.Popen(
                 ~~~~~~~~~~~~~~~~^
        args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        universal_newlines=False, bufsize=bufsize, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/subprocess.py", line 1039, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        pass_fds, cwd, env,
                        ^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                        gid, gids, uid, umask,
                        ^^^^^^^^^^^^^^^^^^^^^^
                        start_new_session, process_group)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/subprocess.py", line 1854, in _execute_child
    self._posix_spawn(args, executable, env, restore_signals, close_fds,
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      p2cread, p2cwrite,
                      ^^^^^^^^^^^^^^^^^^
                      c2pread, c2pwrite,
                      ^^^^^^^^^^^^^^^^^^
                      errread, errwrite)
                      ^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/subprocess.py", line 1798, in _posix_spawn
    self.pid = os.posix_spawn(executable, args, env, **kwargs)
               ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected str, bytes or os.PathLike object, not int

@marmarek
Copy link
Member

I fixed preserving types, and now xid is actually int...

@marmarek
Copy link
Member

marmarek commented Jun 20, 2025

#367

ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 21, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 21, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 21, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
@marmarek
Copy link
Member

I'm merging #367 now, and it will require this PR to be rebased (there is a small conflict).

ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 21, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
@ben-grande
Copy link
Contributor Author

I was worried a bit but the error is this:

Traceback (most recent call last):
  File "/usr/bin/qvm-run", line 5, in <module>
    sys.exit(main())
             ~~~~^^
  File "/usr/lib/python3.13/site-packages/qubesadmin/tools/qvm_run.py", line 288, in main
    sys.stderr.flush()
    ~~~~~~~~~~~~~~~~^^
BlockingIOError: [Errno 11] write could not complete without blocking

So I will just add --no-color-output --no-color-stderr to reduce the cases where the issue can happen.


Now the preload-dispvm-completed feature not being registered in the test events:

Traceback (most recent call last):
  File "/usr/lib64/python3.13/contextlib.py", line 85, in inner
    return func(*args, **kwds)
  File "/usr/lib/python3.13/site-packages/qubes/tests/integ/dispvm.py", line 429, in test_013_dvm_run_preload_gui
    self.loop.run_until_complete(self._test_013_dvm_run_preload_gui())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.13/asyncio/base_events.py", line 719, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/usr/lib/python3.13/site-packages/qubes/tests/integ/dispvm.py", line 437, in _test_013_dvm_run_preload_gui
    await self.run_preload()
  File "/usr/lib/python3.13/site-packages/qubes/tests/integ/dispvm.py", line 352, in run_preload
    self.assertTrue(
    ~~~~~~~~~~~~~~~^
        self._test_event_was_handled(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            dispvm_name, "domain-feature-set:preload-dispvm-completed"
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        )
        ^
    )
    ^
AssertionError: None is not true
diff --git a/qubes/tests/integ/dispvm.py b/qubes/tests/integ/dispvm.py
index f1f6fa23..60de4e31 100644
--- a/qubes/tests/integ/dispvm.py
+++ b/qubes/tests/integ/dispvm.py
@@ -267,7 +267,11 @@ class TC_20_DispVMMixin(object):
         preload_unfinished = preload_dispvm
         for _ in range(60):
             for qube in preload_unfinished.copy():
-                if self.app.domains[qube].preload_complete.is_set():
+                qo = self.app.domains[qube]
+                if qo.preload_complete.is_set():
+                    logger.info("preload completed for '%s'", qube)
+                    feat = qo.features.get("preload-dispvm-completed")
+                    logger.info("preload completed feature '%s'", feat)
                     preload_unfinished.remove(qube)
                     continue
             if not preload_unfinished:
...
INFO: wait_preload: start
INFO: wait_preload: preload completed for 'disp8751'
INFO: wait_preload: preload completed feature '1'
INFO: wait_preload: end
...

======================================================================
FAIL: qubes.tests.integ.dispvm/TC_20_DispVM_debian-12-xfce/test_013_dvm_run_preload_gui (assert_type=True, qube='disp8751', event='domain-feature-set:preload-dispvm-completed', test=True)
  Test preloading with GUI feature enabled and use after
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/user/qubes-core-admin/qubes/tests/integ/dispvm.py", line 375, in run_preload
    self.assertTrue(event_result)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
AssertionError: None is not true

----------------------------------------------------------------------
Ran 1 test in 12.653s

FAILED (failures=1)

The feature is set, but the event handler hasn't registered it yet?

@ben-grande
Copy link
Contributor Author

If I delete the feature on use_preload() in vm/dispvm.py and add handler for domian-feature-delete:preload-dispvm-completed in the run_preload() in tests/integ/dispvm.py, the delete check pass but the set check still doesn't pass.

@marmarek
Copy link
Member

The feature is set, but the event handler hasn't registered it yet?

Maybe the handler is not registered on the correct object? I guess you can add some logging when adding handlers and see which objects get them.

@ben-grande
Copy link
Contributor Author

ben-grande commented Jun 24, 2025

Maybe the handler is not registered on the correct object? I guess you can add some logging when adding handlers and see which objects get them.

Correct, it is not registered at all... will investigate why.

run_preload: start
run_preload_proc: start
_test_event_handler: disp5557[domain-feature-set:preload-dispvm-in-progress]=True
_test_event_handler: disp5557[domain-feature-delete:internal]=True
_test_event_handler: disp5557[domain-feature-delete:preload-dispvm-in-progress]=True
_test_event_handler: disp5557[domain-unpaused]=True
_test_event_handler: test-inst-dvm[domain-preload-dispvm-used]=True
run_preload_proc: end
_test_event_was_handled: disp5557[domain-paused]='None'
_test_event_was_handled: test-inst-dvm[domain-preload-dispvm-autostart]='None'
_test_event_was_handled: test-inst-dvm[domain-preload-dispvm-start]='None'
_test_event_was_handled: test-inst-dvm[domain-preload-dispvm-used]='True'
_test_event_was_handled: disp5557[domain-feature-set:preload-dispvm-in-progress]='True'
_test_event_was_handled: disp5557[domain-feature-delete:preload-dispvm-in-progress]='True'
_test_event_was_handled: disp5557[domain-feature-set:preload-dispvm-completed]='None'
_test_event_was_handled: disp5557[domain-feature-delete:internal]='True'
run_preload: end

@ben-grande
Copy link
Contributor Author

Probably related to the wait_completion, the qube should also have been paused and unpaused, but because adding the event only happens after the qube has finished preloading, it is not gathering the correct result.

ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 24, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 24, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 24, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 24, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 25, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 25, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
ben-grande added a commit to ben-grande/qubes-core-admin that referenced this pull request Jun 26, 2025
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
Requires: QubesOS/qubes-core-admin-client#359
- Autostarted applications don't show when preloading; and
- Preloaded qubes paused before the session will have a working GUI when
  the session starts.

For: QubesOS/qubes-issues#1512
For: QubesOS/qubes-issues#9940
For: QubesOS/qubes-issues#9907
@marmarek marmarek merged commit 9c32984 into QubesOS:main Jun 26, 2025
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants