Skip to content

Commit 0332c49

Browse files
committed
Announcement: Preloaded disposables
1 parent af325a6 commit 0332c49

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
layout: post
3+
title: "Qubes Architecture Next Steps: Preloaded diposables"
4+
categories: articles
5+
author: Benjamin Grande
6+
---
7+
8+
<!--
9+
TODO: reviewer: when posting, rename this file with correct date.
10+
TODO: reviewer: when posting, rewrite the paragraph below:
11+
12+
This is the second article in the "What's new in Qubes 4.3?" series. You
13+
can find the previous one (about GUI Domains)
14+
[here](/news/2020/03/18/gui-domain/). While the
15+
introduction of GUI domains is a big, singular feature, the changes to
16+
qrexec are more complex and varied --- but also very important.
17+
-->
18+
19+
## What are disposables?
20+
21+
A [disposable](/doc/how-to-use-disposables/) is a lightweight qube that can be
22+
created quickly and will self-destruct when closed. Disposables are usually
23+
created in order to host and execute untrusted code, be it on the software
24+
level of single application (like a viewer, editor or web browser) or the
25+
hardware level (e.g., for [PCI passtrough](/doc/how-to-use-pci-devices/)).
26+
27+
There are two kinds of disposables, unnamed and named. The difference between
28+
them (besides one having a fixed name) is that unnamed disposables are
29+
destroyed when closing the first application opened in them while the user
30+
must explicitly shut down named disposables.
31+
32+
## Fresh disposable startup time leads to fatigue
33+
34+
One of the most secure ways to segregate duties is to use a fresh disposable
35+
for every new task. Unnamed disposables are ideal for this use case. So, what
36+
is the problem with them? The caller has to wait for a complete qube startup
37+
before running the desired application. The delay might seem a minor annoyance
38+
at first, but over a prolonged period, fatigued users tend to reuse already
39+
tainted disposables or run applications in non-disposable qubes to avoid the
40+
waiting time.
41+
42+
The problem is not the user's lack of understanding or a lack of documentation
43+
but how the user perceives the system. If the system is slow, many users will
44+
circumvent that slowness even if it means compromising their security, because
45+
they just want to get things done.
46+
47+
The slowdown is aggravated when requesting a high number of disposables
48+
sequentially, which happens constantly when using the Qubes Executor to
49+
[build QubesOS](/doc/qubes-builder-v2/).
50+
51+
A secure workflow should not be a burden. Can Qubes OS do better?
52+
53+
## What are preloaded disposables?
54+
55+
Yes! It can do better.
56+
57+
Qubes OS project lead Marek Marczykowski-Górecki, in his
58+
[Qubes OS development status update](https://cfp.3mdeb.com/qubes-os-summit-2024/talk/AWCBJ8/)
59+
at Qubes OS Summit 2024, mentioned plans for faster disposables in Qubes OS
60+
4.3. Here is where preloaded disposables enters.
61+
62+
Preloaded disposables are unnamed disposables started in the background and
63+
kept hidden from the user when not in use. They are interrupted (paused or
64+
suspended, as appropriate) and resumed (transparently) when a disposable qube
65+
is requested by the user.
66+
67+
When the qube is preloaded, the qube application listing and the qube entry
68+
itself are hidden from GUI applications such as the app menu and the Qrexec
69+
Policy Ask prompt. This is by design to avoid contamination. A preload is not
70+
something intended to be used, but indirectly.
71+
72+
The use of preloaded disposables is transparent, indistinguishable from the
73+
use of unnamed disposables. Requesting the creation of a new unnamed
74+
disposable will instead mark a preload as used and reply with an
75+
already-running preloaded disposable, followed by the creation of a
76+
substitute. A preload that is marked as used ceases to be a preload. Its
77+
applications entries become visible in GUI applications the same way as
78+
standard unnamed disposables.
79+
80+
Usage of disposables that have completed the preloading stage is almost as
81+
fast as executing code on an already-running qube, just a bit slower because
82+
it has to unpause the qube as well as start the GUI agent. While unpause can
83+
take just a few milliseconds, waiting for the GUI agent can take a second. The
84+
remaining time is overhead of operations across [domains](/doc/qrexec/).
85+
86+
In case of a failure to preload for any reason, such as lack of available
87+
memory or the daemon responsible for managing qubes (`qubesd`) having stopped,
88+
no user interaction is needed. The system will fill in gaps of missing
89+
preloaded disposables while removing incomplete ones.
90+
91+
## How to use preloaded disposables
92+
93+
Preloading is a "set and forget" operation. Configure it once, setting the
94+
desired maximum number of preloaded qubes you would like to have preloaded,
95+
and the system takes care of the rest, including filling in the gaps of used
96+
preloaded qubes.
97+
98+
The only action required to preload a disposable is to set the feature
99+
`preload-dispvm-max` on the disposable template you most use for generating
100+
unnamed disposables. Consider a user that does a lot of management operations,
101+
such as [Salt](/doc/salt/) or `qvm-console-dispvm`. The default qube for those
102+
operations is `default-mgmt-dvm`:
103+
104+
[![VM Settings](/attachment/posts/preload-local.png)](/attachment/posts/preload-local.png)
105+
106+
Or use the equivalent command-line operation:
107+
108+
```shell
109+
qvm-features default-mgmt-dvm preload-dispvm-max 2
110+
```
111+
112+
If you use the global `default_dispvm` a lot, you can target the global
113+
preload setting by setting the feature on `dom0`:
114+
115+
[![Global settings](/attachment/posts/preload-global.png)](/attachment/posts/preload-global.png)
116+
117+
Or use the equivalent command-line operation:
118+
119+
```shell
120+
qvm-features dom0 preload-dispvm-max 2
121+
```
122+
123+
While the disposable template remains the global `default_dispvm`, it will
124+
respect the global feature and ignore the per-qube setting.
125+
126+
To remove all the preloaded qubes, set the feature value to `0`, `''` (empty)
127+
or delete the feature. If the feature is set on `dom0`, it's better to delete
128+
the feature so that the preload setting to be read from the disposable
129+
template itself and not capped to `0`.
130+
131+
```shell
132+
qvm-features --delete dom0 preload-dispvm-max
133+
```
134+
135+
The limit on the number of preloaded disposables you can configure depends on
136+
how much your system can handle. If there is not enough available memory to
137+
preload a disposable, it is skipped until another distinct event triggers it.
138+
However, GUI applications that allow preload configuration have a hard limit
139+
of `50`, which should be enough for most use cases.
140+
141+
## Performance improvements
142+
143+
<!--
144+
TODO: ben: graphs here would be nice, but percentage would also be ok I'd say.
145+
146+
- How fast compared to execution in a fresh disposable (use GUI and non-GUI
147+
RPC)
148+
- How fast compared to execution in an already-running qube (use GUI and
149+
non-GUI RPC)
150+
- How much faster have builds become?
151+
152+
-->
153+
154+
## Known issues
155+
156+
Preloaded disposables are paused when they finish preloading and haven't been
157+
requested for use yet. Paused qubes still consume allocated memory, and this
158+
stale state does not allow for [memory redistribution](/doc/qmemman/).
159+
160+
Preloading multiple disposables works even on systems with as low as 8 GB of
161+
RAM, the experience however, may not be the best when there's little available
162+
memory. Users with machines that constantly have a lot of unused memory won't
163+
notice a difference.

0 commit comments

Comments
 (0)