![Marek Marczykowski-Górecki](/assets/img/avatar_default.png)
Use maxmem=0 for disabling dynamic memory balance, instead of cryptic service.meminfo-writer feature. Under the hood, meminfo-writer service is also set based on maxmem property (directly in qubesdb, not vm.features dict). Having this as a property (not "feature"), allow to have sensible handling of default value. Specifically, disable it automatically if otherwise it would crash a VM. This is the case for: - domain with PCI devices (PoD is not supported by Xen then) - domain without balloon driver and/or meminfo-writer service The check for the latter is heuristic (assume presence of 'qrexec' also can indicate balloon driver support), but it is true for currently supported systems. This also allows more reliable control of libvirt config: do not set memory != maxmem, unless qmemman is enabled. memory != maxmem only makes sense if qmemman for given domain is enabled. Besides wasting some domain resources for extra page tables etc, for HVM domains this is harmful, because maxmem-memory difference is made of Popupate-on-Demand pool, which - when depleted - will kill the domain. This means domain without balloon driver will die as soon as will try to use more than initial memory - but without balloon driver it sees maxmem memory and doesn't know about the lower limit. Fixes QubesOS/qubes-issues#4135
187 lines
7.3 KiB
XML
187 lines
7.3 KiB
XML
<domain type="xen">
|
|
{% block basic %}
|
|
<name>{{ vm.name }}</name>
|
|
<uuid>{{ vm.uuid }}</uuid>
|
|
{% if ((vm.virt_mode == 'hvm' and vm.devices['pci'].persistent() | list)
|
|
or vm.maxmem == 0) -%}
|
|
<memory unit="MiB">{{ vm.memory }}</memory>
|
|
{% else -%}
|
|
<memory unit="MiB">{{ vm.maxmem }}</memory>
|
|
{% endif -%}
|
|
<currentMemory unit="MiB">{{ vm.memory }}</currentMemory>
|
|
<vcpu placement="static">{{ vm.vcpus }}</vcpu>
|
|
{% endblock %}
|
|
{% block cpu %}
|
|
{% if vm.virt_mode != 'pv' %}
|
|
<cpu mode='host-passthrough'>
|
|
<!-- disable nested HVM -->
|
|
<feature name='vmx' policy='disable'/>
|
|
<feature name='svm' policy='disable'/>
|
|
<!-- disable SMAP inside VM, because of Linux bug -->
|
|
<feature name='smap' policy='disable'/>
|
|
</cpu>
|
|
{% endif %}
|
|
{% endblock %}
|
|
<os>
|
|
{% block os %}
|
|
{% if vm.virt_mode == 'hvm' %}
|
|
<type arch="x86_64" machine="xenfv">hvm</type>
|
|
<!--
|
|
For the libxl backend libvirt switches between OVMF (UEFI)
|
|
and SeaBIOS based on the loader type. This has nothing to
|
|
do with the hvmloader binary.
|
|
-->
|
|
<loader type="{{ "pflash" if vm.features.check_with_template('uefi', False) else "rom" }}">hvmloader</loader>
|
|
<boot dev="cdrom" />
|
|
<boot dev="hd" />
|
|
{% else %}
|
|
{% if vm.virt_mode == 'pvh' %}
|
|
<type arch="x86_64" machine="xenfv">pvh</type>
|
|
{% else %}
|
|
<type arch="x86_64" machine="xenpv">linux</type>
|
|
{% endif %}
|
|
<kernel>{{ vm.storage.kernels_dir }}/vmlinuz</kernel>
|
|
<initrd>{{ vm.storage.kernels_dir }}/initramfs</initrd>
|
|
{% endif %}
|
|
{% if vm.kernel %}
|
|
<cmdline>root=/dev/mapper/dmroot ro nomodeset console=hvc0 rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 {{ vm.kernelopts }}</cmdline>
|
|
{% endif %}
|
|
{% endblock %}
|
|
</os>
|
|
|
|
<features>
|
|
{% block features %}
|
|
{% if vm.virt_mode != 'pv' %}
|
|
<pae/>
|
|
<acpi/>
|
|
<apic/>
|
|
<viridian/>
|
|
{% endif %}
|
|
|
|
{% if vm.devices['pci'].persistent() | list
|
|
and vm.features.get('pci-e820-host', True) %}
|
|
<xen>
|
|
<e820_host state="on"/>
|
|
</xen>
|
|
{% endif %}
|
|
{% endblock %}
|
|
</features>
|
|
|
|
{% block clock %}
|
|
{% if vm.virt_mode == 'hvm' %}
|
|
{% set timezone = vm.features.check_with_template('timezone', 'localtime').lower() %}
|
|
{% if timezone == 'localtime' %}
|
|
<clock offset="variable" adjustment="0" basis="localtime" />
|
|
{% elif timezone.isdigit() %}
|
|
<clock offset="variable" adjustment="{{ timezone }}" basis="UTC" />
|
|
{% else %}
|
|
<clock offset="variable" adjustment="0" basis="UTC" />
|
|
{% endif %}
|
|
{% else %}
|
|
<clock offset='utc' adjustment='reset'>
|
|
<timer name="tsc" mode="native"/>
|
|
</clock>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block on %}
|
|
<on_poweroff>destroy</on_poweroff>
|
|
<on_reboot>destroy</on_reboot>
|
|
<on_crash>destroy</on_crash>
|
|
{% endblock %}
|
|
|
|
<devices>
|
|
{% block devices %}
|
|
{% set i = 0 %}
|
|
{# TODO Allow more volumes out of the box #}
|
|
{% set dd = ['e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
|
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
|
|
%}
|
|
{% for device in vm.block_devices %}
|
|
<disk type="block" device="{{ device.devtype }}">
|
|
<driver name="phy" />
|
|
<source dev="{{ device.path }}" />
|
|
{% if device.name == 'root' %}
|
|
<target dev="xvda" />
|
|
{% elif device.name == 'private' %}
|
|
<target dev="xvdb" />
|
|
{% elif device.name == 'volatile' %}
|
|
<target dev="xvdc" />
|
|
{% elif device.name == 'kernel' %}
|
|
<target dev="xvdd" />
|
|
{% else %}
|
|
<target dev="xvd{{dd[i]}}" />
|
|
{% set i = i + 1 %}
|
|
{% endif %}
|
|
|
|
{% if not device.rw %}
|
|
<readonly />
|
|
{% endif %}
|
|
|
|
{% if device.domain %}
|
|
<backenddomain name="{{ device.domain }}" />
|
|
{% endif %}
|
|
|
|
{% if device.script %}
|
|
<script path="{{ device.script }}" />
|
|
{% endif %}
|
|
</disk>
|
|
{% endfor %}
|
|
|
|
{# start external devices from xvdi #}
|
|
{% set i = 4 %}
|
|
{% for assignment in vm.devices.block.assignments(True) %}
|
|
{% set device = assignment.device %}
|
|
{% set options = assignment.options %}
|
|
{% include 'libvirt/devices/block.xml' %}
|
|
{% endfor %}
|
|
|
|
{% if vm.netvm %}
|
|
{% include 'libvirt/devices/net.xml' with context %}
|
|
{% endif %}
|
|
|
|
{% for assignment in vm.devices.pci.assignments(True) %}
|
|
{% set device = assignment.device %}
|
|
{% set options = assignment.options %}
|
|
{% include 'libvirt/devices/pci.xml' %}
|
|
{% endfor %}
|
|
|
|
{% if vm.virt_mode == 'hvm' %}
|
|
<!-- server_ip is the address of stubdomain. It hosts it's own DNS server. -->
|
|
<emulator
|
|
{% if vm.features.check_with_template('linux-stubdom', True) %}
|
|
type="stubdom-linux"
|
|
{% else %}
|
|
type="stubdom"
|
|
{% endif %}
|
|
{% if vm.netvm and not
|
|
vm.features.check_with_template('linux-stubdom', True) %}
|
|
cmdline="-net lwip,client_ip={{ vm.ip -}}
|
|
,server_ip={{ vm.dns[1] -}}
|
|
,dns={{ vm.netvm.gateway -}}
|
|
,gw={{ vm.netvm.gateway -}}
|
|
,netmask={{ vm.netmask }}"
|
|
{% endif %}
|
|
{% if vm.stubdom_mem %}
|
|
memory="{{ vm.stubdom_mem * 1024 -}}"
|
|
{% endif %}
|
|
/>
|
|
<input type="tablet" bus="usb"/>
|
|
<video>
|
|
<model type="{{ vm.features.check_with_template('video-model', 'vga') }}"/>
|
|
</video>
|
|
{% if vm.features.check_with_template('linux-stubdom', True) %}
|
|
{# TODO only add qubes gui if gui-agent is not installed in HVM #}
|
|
<graphics type="qubes"/>
|
|
{% endif %}
|
|
{% else %}
|
|
<console type="pty">
|
|
<target type="xen" port="0"/>
|
|
</console>
|
|
{% endif %}
|
|
{% endblock %}
|
|
</devices>
|
|
</domain>
|
|
|
|
<!-- vim: set ft=jinja ts=4 sts=4 sw=4 et tw=80 : -->
|