Load qubes-hcl-report asynchronously and cache it per boot - #332
andreasglashauser wants to merge 1 commit into
Conversation
|
What do you think about doing the caching in the qubes-hcl-report script itself (at least if the yaml-only output is selected)? |
Yeah thats definitely the better way to fix this. I was already working on the Qubes Global Config for another PR and searched for ways to make it more efficient, which is why I implemented this way. |
61c2fb3 to
74eef41
Compare
|
Updated this PR: the caching is gone, so all it does now is move the report collection off the main thread and show placeholder text while it runs. I also dropped the Refresh button that was in the earlier version, it only existed to bypass the cache that used to be here. Caching in the script: QubesOS/qubes-core-admin#877 |
|
some formatting complaints from linters, but otherwise this looks good to me. Good idea, btw. |
|
I tested this version and it works perfectly. Could you squash the linter commit into the main commit? |
Constructing the This Device page ran qubes-hcl-report synchronously on the main thread. The report shells out to sudo lspci -nnvk, sudo dmidecode, xl info and xl dmesg, so the page froze for its duration on every visit. The report now runs in a background thread, with placeholder text shown while it loads. Caching its output is done in qubes-hcl-report itself, so that every caller benefits and the script can decide on the basis of data the tool does not have, such as whether the "xl dmesg" ring buffer was complete. QubesOS/qubes-issues#11081
b845f0a to
7477b70
Compare
Done. |
|
PipelineRetry |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #332 +/- ##
==========================================
+ Coverage 92.79% 92.88% +0.08%
==========================================
Files 66 67 +1
Lines 13844 13910 +66
==========================================
+ Hits 12847 12920 +73
+ Misses 997 990 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
For: QubesOS/qubes-issues#11081
Constructing the This Device page ran
qubes-hcl-report -ysynchronously on the main thread. That script shells out tosudo lspci -nnvk,sudo dmidecode,xl infoandxl dmesg, so the UI was blocked for its duration on every visit to the page.The report now runs in a background thread, showing placeholder text while it loads, and its output is cached.
The cache is keyed on
/proc/sys/kernel/random/boot_id, so it is discarded after a reboot and reused within one. Every field the report contains is fixed for the lifetime of a boot: hardware identity from dmidecode and lspci, the BIOS version, since a firmware flash takes effect only after a reboot, the virtualization fields parsed out of thexl dmesgboot log, since changing VT-d in firmware likewise needs a reboot, and the running kernel and Xen versions. A time-based expiry would re-run the probe when nothing can have changed, and could still miss a change after a reboot inside the window.Two cases are deliberately not cached: a failed run, and a report degraded by an incomplete
xl dmesgring buffer, which emptiesslatand the other virtualization fields. Caching either would make it stick for the rest of the boot. A Refresh button re-runs the report and bypasses the cache, which also covers the one field that can change within a boot, the release string in/etc/qubes-release.New tests in
qubes_config/tests/test_thisdevice.pycover loading, a cache hit, invalidation on a changed boot id, both non-caching cases, and refresh. Since those tests stub out the worker thread andGLib.idle_add, I alsoexercised the real threaded path by running the GUI against
qubesadmin.tests.mock_appand confirming it wrote the cache.Lazy page construction, the other half of #11081, is a separate PR against this repo. The two touch disjoint files and can be merged in either order.
AI disclosure: I did write every code on my own, but I used LLMs for getting reviews & feedback, as well as generating this ticket description from the diff via my own tool running local models.