Skip to content

Commit 662fb94

Browse files
committed
Handle global disposable preload feature
For: QubesOS/qubes-issues#1512 For: QubesOS/qubes-desktop-linux-manager#262
1 parent bf4fcfb commit 662fb94

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

qubes/vm/adminvm.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,71 @@ async def run_service_for_stdio(self, *args, input=None, **kwargs):
347347
)
348348

349349
return stdouterr
350+
351+
@qubes.events.handler("property-set:default_dispvm")
352+
def on_property_set_default_dispvm(
353+
self, event, name, newvalue, oldvalue=None
354+
): # pylint: disable=unused-argument
355+
if newvalue == oldvalue:
356+
return
357+
old_appvm = self.app.domains[oldvalue]
358+
appvm = self.app.domains[newvalue]
359+
appvm.preload_max_ignore_global = False
360+
for qube in [old_appvm, appvm]:
361+
asyncio.ensure_future(
362+
qube.fire_event_async("domain-preload-dispvm-start")
363+
)
364+
365+
@qubes.events.handler("property-del:default_dispvm")
366+
@qubes.events.handler("property-reset:default_dispvm")
367+
def on_property_del_default_dispvm(
368+
self, event, name, oldvalue=None
369+
): # pylint: disable=unused-argument
370+
if oldvalue:
371+
appvm = self.app.domains[oldvalue]
372+
appvm.preload_max_ignore_global = True
373+
asyncio.ensure_future(
374+
appvm.fire_event_async("domain-preload-dispvm-start")
375+
)
376+
377+
@qubes.events.handler("domain-feature-delete:preload-dispvm-max")
378+
def on_feature_delete_preload_dispvm_max(
379+
self, event, feature
380+
): # pylint: disable=unused-argument
381+
appvm = getattr(self, "default_dispvm", None)
382+
if not appvm:
383+
return
384+
appvm.preload_max_ignore_global = True
385+
asyncio.ensure_future(
386+
appvm.fire_event_async("domain-preload-dispvm-start")
387+
)
388+
389+
@qubes.events.handler("domain-feature-pre-set:preload-dispvm-max")
390+
def on_feature_pre_set_preload_dispvm_max(
391+
self, event, feature, value, oldvalue=None
392+
): # pylint: disable=unused-argument
393+
appvm = getattr(self, "default_dispvm", None)
394+
if not appvm:
395+
return
396+
appvm.fire_event(
397+
"domain-feature-pre-set:preload-dispvm-max",
398+
pre_event=True,
399+
feature="preload-dispvm-max",
400+
value=value,
401+
oldvalue=oldvalue,
402+
)
403+
404+
@qubes.events.handler("domain-feature-set:preload-dispvm-max")
405+
def on_feature_set_preload_dispvm_max(
406+
self, event, feature, value, oldvalue=None
407+
): # pylint: disable=unused-argument
408+
appvm = getattr(self, "default_dispvm", None)
409+
if not appvm:
410+
return
411+
appvm.preload_max_ignore_global = False
412+
appvm.fire_event(
413+
"domain-feature-set:preload-dispvm-max",
414+
feature="preload-dispvm-max",
415+
value=value,
416+
oldvalue=oldvalue,
417+
)

qubes/vm/mix/dvmtemplate.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ def on_domain_loaded(self, event): # pylint: disable=unused-argument
9191
def on_feature_delete_preload_dispvm_max(
9292
self, event, feature
9393
): # pylint: disable=unused-argument
94+
if (
95+
self == getattr(self, "default_dispvm", None)
96+
and "preload-dispvm-max" in self.app.domains["dom0"].features
97+
):
98+
return
9499
self.remove_preload_excess(0)
95100

96101
@qubes.events.handler("domain-feature-pre-set:preload-dispvm-max")
@@ -294,11 +299,22 @@ def get_feat_preload(self) -> list[str]:
294299
return value.split(" ") if value else []
295300

296301
def get_feat_preload_max(self) -> int:
297-
"""Get the ``preload-dispvm-max`` feature as an integer."""
302+
"""Get the ``preload-dispvm-max`` feature as an integer.
303+
304+
:param global_feat: ignore global setting.
305+
"""
298306
feature = "preload-dispvm-max"
299307
assert isinstance(self, qubes.vm.BaseVM)
300-
value = self.features.get(feature, 0)
301-
return int(value) if value else 0
308+
default_dispvm = getattr(self.app, "default_dispvm", None)
309+
value = None
310+
if not getattr(self, "preload_max_ignore_global", False):
311+
if self == default_dispvm:
312+
global_features = self.app.domains["dom0"].features
313+
if feature in global_features:
314+
value = global_features.get(feature) or 0
315+
if value is None:
316+
value = self.features.get(feature) or 0
317+
return int(value)
302318

303319
def can_preload(self) -> bool:
304320
"""Returns ``True`` if there is preload vacancy."""

0 commit comments

Comments
 (0)