Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions linux/aux-tools/preload-dispvm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import qubesadmin


def get_preload_max(qube) -> int | None:
"""
Get the ``preload-dispvm-max`` feature as an integer.
:param qubes.vm.qubes.QubesVM qube: Qube to query the feature from.
"""
value = qube.features.get("preload-dispvm-max", None)
return int(value) if value else value

Expand Down
4 changes: 0 additions & 4 deletions qubes/api/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,6 @@ async def vm_volume_import_end(self, untrusted_payload):
async def suspend_pre(self):
"""
Method called before host system goes to sleep.
:return:
"""

preload_templates = qubes.vm.dispvm.get_preload_templates(self.app)
Expand Down Expand Up @@ -346,8 +344,6 @@ async def suspend_pre(self):
async def suspend_post(self):
"""
Method called after host system wake up from sleep.
:return:
"""

# Reload list of previously paused qubes before suspending
Expand Down
21 changes: 21 additions & 0 deletions qubes/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,12 @@ def _domain_event_callback(self, _conn, domain, event, _detail, _opaque):

@qubes.events.handler("domain-pre-delete")
def on_domain_pre_deleted(self, event, vm):
"""
Forbid deleting qube if it is a dependency of another qube.
:param str event: Event which was fired.
:param qubes.vm.QubesVM name: Qube name.
"""
# pylint: disable=unused-argument
for obj in itertools.chain(self.domains, (self,)):
if obj is vm:
Expand Down Expand Up @@ -1733,6 +1739,21 @@ def on_property_set_default_netvm(
def on_property_set_default_dispvm(
self, event, name, newvalue=None, oldvalue=None
):
"""
When system's default_dispvm is (re)set, alert every domain that has
the default value.
If there is a difference between the maximum number of preloaded
disposables configured globally and on the new and old setting, adapt
it to match the current scenario.
:param str event: Event which was fired.
:param str name: Property name.
:param qubes.vm.mix.dvmtemplate.DVMTemplateMixin newvalue: New value \
of the property.
:param qubes.vm.mix.dvmtemplate.DVMTemplateMixin oldvalue: Old value \
of the property.
"""
# pylint: disable=unused-argument
for vm in self.domains:
if hasattr(vm, "default_dispvm") and vm.property_is_default(
Expand Down
51 changes: 45 additions & 6 deletions qubes/vm/adminvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ def xid(self) -> int:
.. seealso:
:py:attr:`qubes.vm.qubesvm.QubesVM.xid`
:return: 0
:rtype: int
"""
return 0

Expand Down Expand Up @@ -351,17 +354,33 @@ async def run_service_for_stdio(self, *args, input=None, **kwargs):
@qubes.events.handler("domain-feature-pre-set:preload-dispvm-threshold")
def on_feature_pre_set_preload_dispvm_threshold(
self, event, feature, value, oldvalue=None
): # pylint: disable=unused-argument
):
"""
Before accepting the ``preload-dispvm-threshold`` feature, validate it.
:param str event: Event which was fired.
:param str feature: Feature name.
:param int value: New value of the feature.
:param int oldvalue: Old value of the feature.
"""
# pylint: disable=unused-argument
value = value or "0"
if not value.isdigit():
raise qubes.exc.QubesValueError(
"Invalid preload-dispvm-threshold value: not a digit"
)

@qubes.events.handler("domain-feature-delete:preload-dispvm-max")
def on_feature_delete_preload_dispvm_max(
self, event, feature
): # pylint: disable=unused-argument
def on_feature_delete_preload_dispvm_max(self, event, feature):
"""
On deletion of the ``preload-dispvm-max`` feature, fire
``domain-preload-dispvm-start`` event on the system's
``default_dispvm``.
:param str event: Event which was fired.
:param str feature: Feature name.
"""
# pylint: disable=unused-argument
if not (appvm := getattr(self.app, "default_dispvm", None)):
return
reason = "global feature was deleted"
Expand All @@ -372,7 +391,16 @@ def on_feature_delete_preload_dispvm_max(
@qubes.events.handler("domain-feature-pre-set:preload-dispvm-max")
def on_feature_pre_set_preload_dispvm_max(
self, event, feature, value, oldvalue=None
): # pylint: disable=unused-argument
):
"""
Before accepting the ``preload-dispvm-max`` feature, validate it.
:param str event: Event which was fired.
:param str feature: Feature name.
:param int value: New value of the feature.
:param int oldvalue: Old value of the feature.
"""
# pylint: disable=unused-argument
if value == oldvalue:
return
if not (appvm := getattr(self.app, "default_dispvm", None)):
Expand All @@ -388,7 +416,18 @@ def on_feature_pre_set_preload_dispvm_max(
@qubes.events.handler("domain-feature-set:preload-dispvm-max")
def on_feature_set_preload_dispvm_max(
self, event, feature, value, oldvalue=None
): # pylint: disable=unused-argument
):
"""
After setting the ``preload-dispvm-max`` feature, fire
``domain-preload-dispvm-start`` event on the system's
``default_dispvm``.
:param str event: Event which was fired.
:param str feature: Feature name.
:param int value: New value of the feature.
:param int oldvalue: Old value of the feature.
"""
# pylint: disable=unused-argument
if value == oldvalue:
return
if not (appvm := getattr(self.app, "default_dispvm", None)):
Expand Down
Loading