From 2de5a8e894fa3a41222460a30188845058434fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Mon, 25 Feb 2019 04:59:46 +0100 Subject: [PATCH] vm,templates: allow to obtain common kernelopts from a kernel package If kernel package ships default-kernelopts-common.txt file, use that instead of hardcoded Linux-specific options. For Linux kernel it may include xen_scrub_pages=0 option, but only if initrd shipped with this kernel re-enable this option later. QubesOS/qubes-issues#4839 QubesOS/qubes-issues#4736 --- qubes/config.py | 2 ++ qubes/tests/vm/qubesvm.py | 67 +++++++++++++++++++++++++++++++++++++++ qubes/vm/qubesvm.py | 19 +++++++++++ templates/libvirt/xen.xml | 2 +- 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/qubes/config.py b/qubes/config.py index da02dbb6..0c3d93a2 100644 --- a/qubes/config.py +++ b/qubes/config.py @@ -69,6 +69,8 @@ defaults = { 'hvm_memory': 400, 'kernelopts': "nopat", 'kernelopts_pcidevs': "nopat iommu=soft swiotlb=8192", + 'kernelopts_common': ('root=/dev/mapper/dmroot ro nomodeset console=hvc0 ' + 'rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 '), 'dom0_update_check_interval': 6*3600, diff --git a/qubes/tests/vm/qubesvm.py b/qubes/tests/vm/qubesvm.py index 42988cfa..bb2f1202 100644 --- a/qubes/tests/vm/qubesvm.py +++ b/qubes/tests/vm/qubesvm.py @@ -867,6 +867,73 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase): self.assertXMLEqual(lxml.etree.XML(libvirt_xml), lxml.etree.XML(expected)) + def test_600_libvirt_xml_hvm_dom0_kernel_kernelopts(self): + expected = ''' + test-inst-test + 7db78950-c467-4863-94d1-af59806384ea + 500 + 400 + 2 + + + + + + + + + hvm + + hvmloader + + + kernel specific options nopat + + + + + + + + + destroy + destroy + destroy + + + + + + + + + ''' + my_uuid = '7db78950-c467-4863-94d1-af59806384ea' + vm = self.get_vm(uuid=my_uuid) + vm.netvm = None + vm.virt_mode = 'hvm' + vm.features['qrexec'] = True + with unittest.mock.patch('qubes.config.qubes_base_dir', + '/tmp/qubes-test'): + kernel_dir = '/tmp/qubes-test/vm-kernels/dummy' + os.makedirs(kernel_dir, exist_ok=True) + open(os.path.join(kernel_dir, 'vmlinuz'), 'w').close() + open(os.path.join(kernel_dir, 'initramfs'), 'w').close() + with open(os.path.join(kernel_dir, + 'default-kernelopts-common.txt'), 'w') as f: + f.write('kernel specific options \n') + self.addCleanup(shutil.rmtree, '/tmp/qubes-test') + vm.kernel = 'dummy' + libvirt_xml = vm.create_config_file() + self.assertXMLEqual(lxml.etree.XML(libvirt_xml), + lxml.etree.XML(expected)) + def test_600_libvirt_xml_pvh(self): expected = ''' test-inst-test diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index e41fcf93..5dbb2596 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -1983,6 +1983,25 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): return None + @property + def kernelopts_common(self): + '''Kernel options which should be used in addition to *kernelopts* + property. + + This is specific to kernel (and initrd if any) + ''' + if not self.kernel: + return '' + kernels_dir = self.storage.kernels_dir + + kernelopts_path = os.path.join(kernels_dir, + 'default-kernelopts-common.txt') + if os.path.exists(kernelopts_path): + with open(kernelopts_path) as f_kernelopts: + return f_kernelopts.read().rstrip('\n\r') + else: + return qubes.config.defaults['kernelopts_common'] + # # helper methods # diff --git a/templates/libvirt/xen.xml b/templates/libvirt/xen.xml index 8f3f7162..9176c9ae 100644 --- a/templates/libvirt/xen.xml +++ b/templates/libvirt/xen.xml @@ -47,7 +47,7 @@ {% if vm.features.check_with_template('no-default-kernelopts', False) -%} {{ vm.kernelopts }} {% else -%} - root=/dev/mapper/dmroot ro nomodeset console=hvc0 rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 {{ vm.kernelopts }} + {{ vm.kernelopts_common }}{{ vm.kernelopts }} {% endif -%} {% endif %} {% endblock %}