1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 11:46:49 +00:00

fix(instances): new q35 VMs have spare PCIe ports, and a full VM says what to do

On a q35 machine each PCIe device (a virtio disk, a network card) takes
a root port of its own, libvirt makes only as many ports as the VM is
defined with, and a running VM gets no new one: adding a virtio disk to
such a VM failed with libvirt's "No more available PCI slots".

A new q35 VM is now defined with the PCIe root and 14 root ports, as
virt-install makes them: libvirt puts the VM's devices into them and
leaves the rest free for devices added while it runs.

When a running VM has no free slot, Add disk and Add network device say
what to do instead of libvirt's words: for a disk, the scsi bus when
the VM has a SCSI controller (its disks need no slot of their own), or
adding it with the VM shut down, where libvirt makes the port; for a
network device, shutting the VM down. A new volume whose attach was
refused stays in its pool, as before, to attach as an existing volume.
This commit is contained in:
catborise 2026-10-31 19:21:14 +03:00
parent 27b8dd4f1b
commit fe4cffdc91
3 changed files with 216 additions and 69 deletions

View file

@ -9,6 +9,8 @@ from vrtManager.connection import wvmConnect
# libvirt's CPU modes a new VM can have; any other value is a CPU model's name (mode custom)
CPU_MODES = ("host-model", "host-passthrough", "maximum")
# the PCIe root ports of a new q35 VM, its devices' and the spare ones together
PCIE_ROOT_PORTS = 14
def cpu_choices(dom_caps):
@ -379,7 +381,14 @@ class wvmCreate(wvmConnect):
xml += f""" <video>
<model type='{video}'/>
</video>
</video>"""
# q35 plugs each PCIe device (a virtio disk, a NIC) into a root port of
# its own and libvirt makes only as many as the VM is defined with: as
# virt-install, 14 ports, so a running VM can take more devices
if "q35" in machine:
xml += "<controller type='pci' model='pcie-root'/>"
xml += "<controller type='pci' model='pcie-root-port'/>" * PCIE_ROOT_PORTS
xml += """
</devices>
</domain>"""
return self._defineXML(xml)