Delay connecting with gui-daemon until after starting Xorg#251
Delay connecting with gui-daemon until after starting Xorg#251marmarek wants to merge 2 commits intoQubesOS:mainfrom
Conversation
|
@ben-grande I've looked at gui-agent and I think this should be enough to start user session without waiting for GUI daemon. See above description for specific details. Generally, this should allow using This is only lightly tested, needs checking for various corner cases. A few cases that are worth testing:
When I write "start gui-daemon", I mean the whole thing that qvm-start-daemon does, including qubes.SetMonitorLayout call. There are probably some more cases to test, I hope you'll think of something :) |
c746876 to
3e53341
Compare
|
Thanks for the PR, seems very good. Will make the GUI connection much faster. Apart from this PR, I think just some other PRs are needed:
But that is mostly it (besides testing all scenarios). |
|
Actually, I think the qvm-start-daemon should retain is_preload check - this PR makes it possible to start user session still without gui daemon. |
OpenQA test summaryComplete test suite and dependencies: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2026020318-4.3&flavor=pull-requests Test run included the following:
New failures, excluding unstableCompared to: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2026011214-devel&flavor=update
Failed tests22 failures
Fixed failuresCompared to: https://openqa.qubes-os.org/tests/165203#dependencies 12 fixed
Unstable testsDetailsPerformance TestsPerformance degradation:14 performance degradations
Remaining performance tests:97 tests
|
|
Unexpected side effect: notification proxy starts earlier, before user logs in, and fails to connect to (not running yet) notification daemon in dom0: QubesOS/qubes-video-companion#33 (comment) |
|
This also breaks (kinda) sys-gui... Xephyr gets started with wrong resolution (the hardcoded 1920x1080, instead of what dom0 sends). I'm not sure why, could be startup timing, but maybe sending monitor layout is broken with sys-gui. |
When running sys-gui, there are two X servers. The one on :1 is actually connected to dom0, adjust resolution/monitor layout there. The internal one likely need adjustment too, but leave that for later This hopefully will be enough to unbreak sys-gui with QubesOS#251
This allows Xephyr to automatically resize on resolution change. On the other hand, this breaks multi-monitor support in sys-gui even more... It used to be all monitors combined into a single screen in sys-gui (with no metadata about the split), and no way to dynamically change the layout (including dynamically connecting/disconnecting some). Now the first one will work, including dynamic resolution change, but all the others will be ignored (remain black). This dynamic resolution change makes it work again with late gui-daemon connection, see QubesOS#251 Since sys-gui is mostly fallback option in case sys-gui-gpu cannot be used for some reason, it can have limitations.
Sigh... this is another side effect of this PR. The input proxy should retry once dom0 user logs in (to display qrexec prompt, if set to 'ask'). It used to be done via /etc/xdg/autostart in the VM, but now it's started too early (before user logs in). |
Until now, Xorg was started only after connecting with gui-daemon and receiving xconf message. This was mostly because initial resolution/video mem specified in the xorg.conf couldn't later be changed and that affects maximum working resolution. Since 49420c5 "Increase screen pixmap size beyond initial video RAM if needed", this is no longer a problem. The only parameter (still) needed before starting Xorg is GUI domain id, but this is available on the command line. Change gui-agent to start Xorg earlier and only then wait for gui-daemon. This allows starting all of the user session earlier, optimizing startup time. This is especially relevant for VMs started on boot (before user logs in), when GUI daemon isn't started yet. And also helpful for preloaded disposables, which may start user session as part of preloading now. The current implementation is rather naive: it starts Xorg with hardcoded 1920x1080 resolution (which will later be updated by the qubes.SetMonitorLayout qrexec call), selects which events it want to receive and then waits for the GUI daemon. Especially, no events are actually processed before GUI daemon connects. This assumes all events will be queued and can be processed after GUI daemon connection. Very similar approach is already taken on GUI daemon re-connection, and it works. This makes the msg_xconf sent by the gui-daemon completely ignored. There is a potential issue, if too many events get queued before GUI daemon connects and some get dropped. It's unclear how Xlib handles that (and what is the limit), but if that happens there are two alternative solutions: 1. Start processing events normally, especially collect info about all relevant windows, but dont send anything to GUI daemon before it connects - this basically requires changing write_struct() (and other similar places) to check if GUI daemon is connected. And once GUI daemon connects (first event received on the vchan FD), call send_all_windows_info(). 2. Wait for GUI daemon before registering for events, but then iterate over all windows to collect necessary info and send it to dom0. This approach theoretically can be more reliable (and might even allow restarting gui-agent without restarting Xorg as a side effect), but it's unclear if all data can be rebuilt this way. Especially tray icons may be problematic, as it isn't any window property, but a message sent to relevant selection owner (but theoretically https://tronche.com/gui/x/icccm/sec-2.html#s-2.8 provides solution for this issue). Announce the feature as `late-gui-daemon`. QubesOS/qubes-issues#9940 (comment)
Create /run/qubes/gui-agent.status with one of the following lines: - starting - GUI agent is starting (Xorg, initial settings etc) - started - GUI agent is started, applications can start normally, but GUI daemon isn't connected yet - connected - GUI daemon connected, user can now interact with the applications Besides diagnostic information, this also can be used by applications to wait for GUI daemon to connect - by using inotify on the file. QubesOS/qubes-issues#9940
89fd8c1 to
a981e36
Compare
Wait for GUI agent to report that GUI daemon has connected. This in practice waits for the user to log into GUI domain (or dom0). This is relevant if the qrexec policy for qubes.Input* is set to ask - if the user is not logged in yet, the qrexec prompt cannot be displayed, and the qrexec prompt would be denied. Keep the change compatible with the old GUI agent (the same package may be installed on R4.2) - if the status file is not there, skip the wait. And to make the update least intrusive, only recommend pyinotify, but if it's not there, fallback to polling the file. QubesOS/qubes-issues#9940 QubesOS/qubes-gui-agent-linux#251 (comment)
Or if GUID of the client can be found on the server. This script will be replicated to qubes-core-agent-linux. For: QubesOS/qubes-notification-proxy#13 For: QubesOS/qubes-gui-agent-linux#251 For: QubesOS/qubes-core-admin#757 For: QubesOS/qubes-issues#1512 For: QubesOS/qubes-issues#9940 Fixes: QubesOS/qubes-issues#10443
With the GUI agent patch, it can start before the GUI daemon connects, allowing the user session to complete. Wait both services to guarantee no enabled user or system service tries to start after the preload is used. Requires: QubesOS/qubes-gui-agent-linux#251 Fixes: QubesOS/qubes-issues#9940 For: QubesOS/qubes-issues#1512
With the GUI agent patch, it can start before the GUI daemon connects, allowing the user session to complete. Wait both services to guarantee no enabled user or system service tries to start after the preload is used. Requires: QubesOS/qubes-gui-agent-linux#251 Requires: QubesOS/qubes-gui-agent-linux#255 Fixes: QubesOS/qubes-issues#9940 For: QubesOS/qubes-issues#1512
With the GUI agent patch, it can start before the GUI daemon connects, allowing the user session to complete. Wait both services to guarantee no enabled user or system service tries to start after the preload is used. Requires: QubesOS/qubes-gui-agent-linux#251 Requires: QubesOS/qubes-gui-agent-linux#255 Fixes: QubesOS/qubes-issues#9940 For: QubesOS/qubes-issues#1512
Or if GUID of the client can be found on the server. This script will be replicated to qubes-core-agent-linux. For: QubesOS/qubes-notification-proxy#13 For: QubesOS/qubes-gui-agent-linux#251 For: QubesOS/qubes-core-admin#757 For: QubesOS/qubes-issues#1512 For: QubesOS/qubes-issues#9940 Fixes: QubesOS/qubes-issues#10443
It is also used by dom0, to avoid duplication, merge into a single package. For: QubesOS/qubes-notification-proxy#13 For: QubesOS/qubes-gui-agent-linux#251 For: QubesOS/qubes-core-admin#757 For: QubesOS/qubes-issues#1512 For: QubesOS/qubes-issues#9940 Fixes: QubesOS/qubes-issues#10443
With the GUI agent patch, it can start before the GUI daemon connects, allowing the user session to complete. Wait both services to guarantee no enabled user or system service tries to start after the preload is used. Requires: QubesOS/qubes-gui-agent-linux#251 Requires: QubesOS/qubes-gui-agent-linux#255 Fixes: QubesOS/qubes-issues#9940 For: QubesOS/qubes-issues#1512
With the GUI agent patch, it can start before the GUI daemon connects, allowing the user session to complete. Wait both services to guarantee no enabled user or system service tries to start after the preload is used. Requires: QubesOS/qubes-gui-agent-linux#251 Requires: QubesOS/qubes-gui-agent-linux#255 Fixes: QubesOS/qubes-issues#9940 For: QubesOS/qubes-issues#1512
Until now, Xorg was started only after connecting with gui-daemon and
receiving xconf message. This was mostly because initial
resolution/video mem specified in the xorg.conf couldn't later be
changed and that affects maximum working resolution.
Since 49420c5 "Increase screen pixmap size beyond initial video RAM if
needed", this is no longer a problem. The only parameter (still) needed
before starting Xorg is GUI domain id, but this is available on the
command line. Change gui-agent to start Xorg earlier and only then wait
for gui-daemon. This allows starting all of the user session earlier,
optimizing startup time. This is especially relevant for VMs started on
boot (before user logs in), when GUI daemon isn't started yet. And also
helpful for preloaded disposables, which may start user session as part
of preloading now.
The current implementation is rather naive: it starts Xorg with
hardcoded 1920x1080 resolution (which will later be updated by the
qubes.SetMonitorLayout qrexec call), selects which events it want to
receive and then waits for the GUI daemon. Especially, no events are
actually processed before GUI daemon connects. This assumes all events
will be queued and can be processed after GUI daemon connection. Very
similar approach is already taken on GUI daemon re-connection, and it
works.
There is a potential issue, if too many events get queued before GUI
daemon connects and some get dropped. It's unclear how Xlib handles that
(and what is the limit), but if that happens there are two alternative
solutions:
Start processing events normally, especially collect info about all
relevant windows, but dont send anything to GUI daemon before it
connects - this basically requires changing write_struct() (and other
similar places) to check if GUI daemon is connected. And once GUI daemon
connects (first event received on the vchan FD), call
send_all_windows_info().
Wait for GUI daemon before registering for events, but then iterate
over all windows to collect necessary info and send it to dom0. This
approach theoretically can be more reliable (and might even allow
restarting gui-agent without restarting Xorg as a side effect), but it's
unclear if all data can be rebuilt this way. Especially tray icons may
be problematic, as it isn't any window property, but a message sent to
relevant selection owner (but theoretically
https://tronche.com/gui/x/icccm/sec-2.html#s-2.8 provides
solution for this issue).
QubesOS/qubes-issues#9940 (comment)