xen.xml 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <domain type="xen">
  2. {% block basic %}
  3. <name>{{ vm.name }}</name>
  4. <uuid>{{ vm.uuid }}</uuid>
  5. {% if ((vm.virt_mode == 'hvm' and vm.devices['pci'].persistent() | list)
  6. or vm.maxmem == 0) -%}
  7. <memory unit="MiB">{{ vm.memory }}</memory>
  8. {% else -%}
  9. <memory unit="MiB">{{ vm.maxmem }}</memory>
  10. {% endif -%}
  11. <currentMemory unit="MiB">{{ vm.memory }}</currentMemory>
  12. <vcpu placement="static">{{ vm.vcpus }}</vcpu>
  13. {% endblock %}
  14. {% block cpu %}
  15. {% if vm.virt_mode != 'pv' %}
  16. <cpu mode='host-passthrough'>
  17. <!-- disable nested HVM -->
  18. <feature name='vmx' policy='disable'/>
  19. <feature name='svm' policy='disable'/>
  20. <!-- disable SMAP inside VM, because of Linux bug -->
  21. <feature name='smap' policy='disable'/>
  22. {% if vm.app.host.cpu_family_model in [(6, 58), (6, 62)] -%}
  23. <feature name='rdrand' policy='disable'/>
  24. {% endif -%}
  25. </cpu>
  26. {% endif %}
  27. {% endblock %}
  28. <os>
  29. {% block os %}
  30. {% if vm.virt_mode == 'hvm' %}
  31. <type arch="x86_64" machine="xenfv">hvm</type>
  32. <!--
  33. For the libxl backend libvirt switches between OVMF (UEFI)
  34. and SeaBIOS based on the loader type. This has nothing to
  35. do with the hvmloader binary.
  36. -->
  37. <loader type="{{ "pflash" if vm.features.check_with_template('uefi', False) else "rom" }}">hvmloader</loader>
  38. <boot dev="cdrom" />
  39. <boot dev="hd" />
  40. {% else %}
  41. {% if vm.virt_mode == 'pvh' %}
  42. <type arch="x86_64" machine="xenpvh">xenpvh</type>
  43. {% else %}
  44. <type arch="x86_64" machine="xenpv">linux</type>
  45. {% endif %}
  46. <kernel>{{ vm.storage.kernels_dir }}/vmlinuz</kernel>
  47. <initrd>{{ vm.storage.kernels_dir }}/initramfs</initrd>
  48. {% endif %}
  49. {% if vm.kernel %}
  50. {% if vm.features.check_with_template('no-default-kernelopts', False) -%}
  51. <cmdline>{{ vm.kernelopts }}</cmdline>
  52. {% else -%}
  53. <cmdline>{{ vm.kernelopts_common }}{{ vm.kernelopts }}</cmdline>
  54. {% endif -%}
  55. {% endif %}
  56. {% endblock %}
  57. </os>
  58. <features>
  59. {% block features %}
  60. {% if vm.virt_mode != 'pv' %}
  61. <pae/>
  62. <acpi/>
  63. <apic/>
  64. <viridian/>
  65. {% endif %}
  66. {% if vm.devices['pci'].persistent() | list
  67. and vm.features.get('pci-e820-host', True) %}
  68. <xen>
  69. <e820_host state="on"/>
  70. </xen>
  71. {% endif %}
  72. {% endblock %}
  73. </features>
  74. {% block clock %}
  75. {% if vm.virt_mode == 'hvm' %}
  76. {% set timezone = vm.features.check_with_template('timezone', 'localtime').lower() %}
  77. {% if timezone == 'localtime' %}
  78. <clock offset="variable" adjustment="0" basis="localtime" />
  79. {% elif timezone.isdigit() %}
  80. <clock offset="variable" adjustment="{{ timezone }}" basis="utc" />
  81. {% else %}
  82. <clock offset="variable" adjustment="0" basis="utc" />
  83. {% endif %}
  84. {% else %}
  85. <clock offset='utc' adjustment='reset'>
  86. <timer name="tsc" mode="native"/>
  87. </clock>
  88. {% endif %}
  89. {% endblock %}
  90. {% block on %}
  91. <on_poweroff>destroy</on_poweroff>
  92. <on_reboot>destroy</on_reboot>
  93. <on_crash>destroy</on_crash>
  94. {% endblock %}
  95. <devices>
  96. {% block devices %}
  97. {#
  98. HACK: The letter counter is implemented in this way because
  99. Jinja does not allow you to increment variables in a loop
  100. anymore. As of Jinja 2.10, we will be able to replace this
  101. with:
  102. {% set counter = namespace(i=0) %}
  103. {% set counter.i = counter.i + 1 %}
  104. #}
  105. {% set counter = {'i': 0} %}
  106. {# TODO Allow more volumes out of the box #}
  107. {% set dd = ['e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
  108. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
  109. %}
  110. {% for device in vm.block_devices %}
  111. <disk type="block" device="{{ device.devtype }}">
  112. <driver name="phy" />
  113. <source dev="{{ device.path }}" />
  114. {% if device.name == 'root' %}
  115. <target dev="xvda" />
  116. {% elif device.name == 'private' %}
  117. <target dev="xvdb" />
  118. {% elif device.name == 'volatile' %}
  119. <target dev="xvdc" />
  120. {% elif device.name == 'kernel' %}
  121. <target dev="xvdd" />
  122. {% else %}
  123. <target dev="xvd{{dd[counter.i]}}" />
  124. {% if counter.update({'i': counter.i + 1}) %}{% endif %}
  125. {% endif %}
  126. {% if not device.rw %}
  127. <readonly />
  128. {% endif %}
  129. {% if device.domain %}
  130. <backenddomain name="{{ device.domain }}" />
  131. {% endif %}
  132. {% if device.script %}
  133. <script path="{{ device.script }}" />
  134. {% endif %}
  135. </disk>
  136. {% endfor %}
  137. {# start external devices from xvdi #}
  138. {% set counter = {'i': 4} %}
  139. {% for assignment in vm.devices.block.assignments(True) %}
  140. {% set device = assignment.device %}
  141. {% set options = assignment.options %}
  142. {% include 'libvirt/devices/block.xml' %}
  143. {% endfor %}
  144. {% if vm.netvm %}
  145. {% include 'libvirt/devices/net.xml' with context %}
  146. {% endif %}
  147. {% for assignment in vm.devices.pci.assignments(True) %}
  148. {% set device = assignment.device %}
  149. {% set options = assignment.options %}
  150. {% include 'libvirt/devices/pci.xml' %}
  151. {% endfor %}
  152. {% if vm.virt_mode == 'hvm' %}
  153. <!-- server_ip is the address of stubdomain. It hosts it's own DNS server. -->
  154. <emulator
  155. {% if vm.features.check_with_template('linux-stubdom', True) %}
  156. type="stubdom-linux"
  157. {% else %}
  158. type="stubdom"
  159. {% endif %}
  160. {% if vm.netvm %}
  161. {% if vm.features.check_with_template('linux-stubdom', True) %}
  162. cmdline="-qubes-net:client_ip={{ vm.ip -}}
  163. ,dns_0={{ vm.dns[0] -}}
  164. ,dns_1={{ vm.dns[1] -}}
  165. ,gw={{ vm.netvm.gateway -}}
  166. ,netmask={{ vm.netmask }}"
  167. {% else %}
  168. cmdline="-net lwip,client_ip={{ vm.ip -}}
  169. ,server_ip={{ vm.dns[1] -}}
  170. ,dns={{ vm.dns[0] -}}
  171. ,gw={{ vm.netvm.gateway -}}
  172. ,netmask={{ vm.netmask }}"
  173. {% endif %}
  174. {% endif %}
  175. {% if vm.stubdom_mem %}
  176. memory="{{ vm.stubdom_mem * 1024 -}}"
  177. {% endif %}
  178. />
  179. <input type="tablet" bus="usb"/>
  180. {% if vm.features.check_with_template('audio-model', False) %}
  181. <sound model="{{ vm.features.check_with_template('audio-model', False) }}"/>
  182. {% endif %}
  183. {% if vm.features.check_with_template('video-model', 'vga') != 'none' %}
  184. <video>
  185. <model type="{{ vm.features.check_with_template('video-model', 'vga') }}"/>
  186. </video>
  187. {% if vm.features.check_with_template('linux-stubdom', True) %}
  188. {# TODO only add qubes gui if gui-agent is not installed in HVM #}
  189. <graphics type="qubes"/>
  190. {% endif %}
  191. {% endif %}
  192. {% endif %}
  193. <console type="pty">
  194. <target type="xen" port="0"/>
  195. </console>
  196. {% endblock %}
  197. </devices>
  198. </domain>
  199. <!-- vim: set ft=jinja ts=4 sts=4 sw=4 et tw=80 : -->