<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="xenpvh">xenpvh</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 %} {% if vm.features.check_with_template('no-default-kernelopts', False) -%} <cmdline>{{ vm.kernelopts }}</cmdline> {% else -%} <cmdline>{{ vm.kernelopts_common }}{{ vm.kernelopts }}</cmdline> {% endif -%} {% 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 %} {# HACK: The letter counter is implemented in this way because Jinja does not allow you to increment variables in a loop anymore. As of Jinja 2.10, we will be able to replace this with: {% set counter = namespace(i=0) %} {% set counter.i = counter.i + 1 %} #} {% set counter = {'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[counter.i]}}" /> {% if counter.update({'i': counter.i + 1}) %}{% endif %} {% 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 counter = {'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 %} {% if vm.features.check_with_template('linux-stubdom', True) %} cmdline="-qubes-net:client_ip={{ vm.ip -}} ,dns_0={{ vm.dns[0] -}} ,dns_1={{ vm.dns[1] -}} ,gw={{ vm.netvm.gateway -}} ,netmask={{ vm.netmask }}" {% else %} cmdline="-net lwip,client_ip={{ vm.ip -}} ,server_ip={{ vm.dns[1] -}} ,dns={{ vm.dns[0] -}} ,gw={{ vm.netvm.gateway -}} ,netmask={{ vm.netmask }}" {% endif %} {% 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 %} {% endif %} <console type="pty"> <target type="xen" port="0"/> </console> {% endblock %} </devices> </domain> <!-- vim: set ft=jinja ts=4 sts=4 sw=4 et tw=80 : -->