From 7b9becbf70ee01194c81bdfadd2992dc2e65a828 Mon Sep 17 00:00:00 2001 From: Ben Grande Date: Tue, 19 Aug 2025 10:03:14 +0200 Subject: [PATCH] Skip backup of undesirable preload feature For: https://github.com/QubesOS/qubes-issues/issues/1512 --- qubes/backup.py | 6 ++++++ qubes/tests/integ/backup.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/qubes/backup.py b/qubes/backup.py index 9b97e9daf..6335b212b 100644 --- a/qubes/backup.py +++ b/qubes/backup.py @@ -833,6 +833,12 @@ async def backup_do(self): backup_app.domains[qid].features["backup-content"] = True backup_app.domains[qid].features["backup-path"] = vm_info.subdir backup_app.domains[qid].features["backup-size"] = vm_info.size + for feature in backup_app.domains[qid].features.copy(): + if ( + feature.startswith("preload-dispvm") + and feature != "preload-dispvm-max" + ): + del backup_app.domains[qid].features[feature] # VM running private volumes without snapshoting them # (revision_to_keep = -1) must be powered off to be backup diff --git a/qubes/tests/integ/backup.py b/qubes/tests/integ/backup.py index 76ecc4cfd..569a02c1d 100644 --- a/qubes/tests/integ/backup.py +++ b/qubes/tests/integ/backup.py @@ -174,6 +174,22 @@ def create_backup_vms(self, pool=None): self.loop.run_until_complete(testvm4.create_on_disk(pool=pool)) vms.append(testvm4) + vmname = self.make_vm_name("dvm") + self.log.debug("Creating %s" % vmname) + testvm5 = self.app.add_new_vm( + qubes.vm.appvm.AppVM, + name=vmname, + template=testvm3, + label="red", + template_for_dispvms=True, + ) + self.loop.run_until_complete(testvm5.create_on_disk(pool=pool)) + testvm5.features["qrexec"] = True + testvm5.features["supported-rpc.qubes.WaitForRunningSystem"] = True + testvm5.features["preload-dispvm-max"] = 0 + testvm5.features["preload-dispvm"] = "" + vms.append(testvm5) + self.app.save() return vms @@ -318,6 +334,7 @@ def get_vms_info(self, vms): vm_info = { "properties": {}, "default": {}, + "features": {}, "devices": {}, } for prop in ( @@ -328,7 +345,7 @@ def get_vms_info(self, vms): "kernelopts", "services", "vcpus", - "features" "include_in_backups", + "include_in_backups", "default_user", "qrexec_timeout", "autostart", @@ -343,6 +360,7 @@ def get_vms_info(self, vms): continue vm_info["properties"][prop] = str(getattr(vm, prop)) vm_info["default"][prop] = vm.property_is_default(prop) + vm_info["features"].update(vm.features) for dev_class in vm.devices.keys(): vm_info["devices"][dev_class] = {} for ass in vm.devices[dev_class].get_assigned_devices(): @@ -379,6 +397,20 @@ def assertCorrectlyRestored(self, vms_info, orig_hashes): vm_name, prop ), ) + for feature in vm_info["features"]: + if ( + feature.startswith("preload-dispvm") + and feature != "preload-dispvm-max" + ): + self.assertIsNone(restored_vm.features.get(feature, None)) + continue + self.assertEqual( + vm_info["features"][feature], + restored_vm.features.get(feature), + "VM {} - feature {} not properly restored".format( + vm_name, feature + ), + ) for dev_class in vm_info["devices"]: for dev in vm_info["devices"][dev_class]: found = False