From 087a02c7f493dcb7da006d9d5fab204321b97c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 15 Nov 2018 15:02:14 +0100 Subject: [PATCH] ext/services: add automatic migration meminfo-writer=False -> maxmem=0 Migrate meminfo-writer=False service setting to maxmem=0 as a method to disable dynamic memory management. Remove the service from vm.features dict in the process. Additionally, translate any attempt to set the service.meminfo-writer feature to either setting maxmem=0 or resetting it to the default (which is memory balancing enabled if supported by given domain). This is to at least partially not break existing tools using service.meminfo-writer as a way to control dynamic memory management. This code does _not_ support reading service.meminfo-writer feature state to get the current state of dynamic memory management, as it would require synchronizing with all the factors affecting its value. One of main reasons for migrating to maxmem=0 approach is to avoid the need of such synchronization. QubesOS/qubes-issues#4480 --- qubes/ext/services.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/qubes/ext/services.py b/qubes/ext/services.py index cb9cd5f7..52557d89 100644 --- a/qubes/ext/services.py +++ b/qubes/ext/services.py @@ -47,6 +47,20 @@ class ServicesExtension(qubes.ext.Extension): def on_domain_feature_set(self, vm, event, feature, value, oldvalue=None): '''Update /qubes-service/ QubesDB tree in runtime''' # pylint: disable=unused-argument + + # TODO: remove this compatibility hack in Qubes 4.1 + if feature == 'service.meminfo-writer': + # if someone try to enable meminfo-writer ... + if value: + # ... reset maxmem to default + vm.maxmem = qubes.property.DEFAULT + else: + # otherwise, set to 0 + vm.maxmem = 0 + # in any case, remove the entry, as it does not indicate memory + # balancing state anymore + del vm.features['service.meminfo-writer'] + if not vm.is_running(): return if not feature.startswith('service.'): @@ -65,8 +79,22 @@ class ServicesExtension(qubes.ext.Extension): if not feature.startswith('service.'): return service = feature[len('service.'):] + # this one is excluded from user control + if service == 'meminfo-writer': + return vm.untrusted_qdb.rm('/qubes-service/{}'.format(service)) + @qubes.ext.handler('domain-load') + def on_domain_load(self, vm, event): + '''Migrate meminfo-writer service into maxmem''' + # pylint: disable=no-self-use,unused-argument + if 'service.meminfo-writer' in vm.features: + # if was set to false, force maxmem=0 + # otherwise, simply ignore as the default is fine + if not vm.features['service.meminfo-writer']: + vm.maxmem = 0 + del vm.features['service.meminfo-writer'] + @qubes.ext.handler('features-request') def supported_services(self, vm, event, untrusted_features): '''Handle advertisement of supported services'''