5.5 KiB
luci-app-qemu-vms
Web UI for QEMU Virtual Machines Simple (VMS) — a lightweight OpenWrt package for running and managing QEMU virtual machines from LuCI, aimed at x86_64 routers/gateways with enough RAM and a spare CPU to spare on a VM or two.
This app is the LuCI frontend for the qemu-vms
backend package (init script + UCI config). It does not work standalone —
qemu-vms must be installed as well (it is pulled in automatically as a
dependency).
Requirements
- x86_64 target only. The backend unconditionally starts guests with
-enable-kvm, and KVM acceleration only works when the guest architecture matches the host's — there is no cross-architecture KVM. Both packages are gated toTARGET_x86_64in their Makefiles and won't even appear inmenuconfigon other targets. - Hardware virtualization (VT-x/AMD-V) enabled in the host BIOS,
/dev/kvmpresent. - For PCI passthrough: IOMMU enabled in BIOS and on the kernel command
line (
intel_iommu=on/amd_iommu=on, plusiommu=ptrecommended). - Dependencies (pulled in automatically):
qemu-x86_64-softmmu,qemu-bridge-helper,minicom,socat,ttyd,usbutils,pciutils.
What it does
Status tab
- Add / edit / delete VMs through a form (memory, vCPUs, CPU model, machine chipset, disk image, disk bus, optional CD-ROM, custom raw QEMU arguments, console type).
- Start / Stop / Restart individual VMs without touching the shell.
- Live status: running/stopped, PID, host-side RAM usage (RSS), disk image size — polled every few seconds.
- Console: opens an in-browser terminal (via
ttyd, spawned on demand on an ephemeral port) attached to the VM's serial console. - VNC: for VMs configured with a graphical display, opens an embedded noVNC viewer over the VM's websocket port.
- Log: shows the VM's host-side lifecycle log
(
/var/log/qemu-vms/<vm>.log) — start attempts, passthrough bind results, configuration warnings, and QEMU's own stderr (KVM errors, missing image, etc.). This is deliberately separate from the guest's own serial console output, and is available even for VNC-mode VMs that have no serial console at all.
Networks tab
Define reusable virtual network interfaces (tap), independent of any
one VM — the same interface definition can be attached to multiple VMs.
Each interface has:
- an optional MAC address (leave blank to auto-generate one with the
52:54:00:31:xx:xxprefix on save), - a tap interface name,
- an optional bridge to enslave the tap into (brought up by
/etc/qemu-ifupat VM start — if no bridge is set, the interface is just brought up standalone), - an emulated network card model (defaults to
virtio-net-pci).
Hardware passthrough tab
Two tables — PCI devices and USB devices — scanned live from the host
(via lspci/lsusb, falling back to raw /sys parsing if those tools
aren't installed).
- Create passthrough: creates a named
pci-passthrough/usb-passthroughUCI section for the device (you choose the section name), which VMs can then reference. For PCI, this unbinds the device (and everything else sharing its IOMMU group) from its current driver and binds it tovfio-pci; for USB, the device is unbound from its kernel driver so QEMU can access it directly. - Remove passthrough: only available once the device isn't attached to any VM. Removes the UCI section.
- The original driver each device was using is recorded before it's ever touched, so it can be restored later — see Detaching hardware below.
Devices are matched by PCI address (pci_id, e.g. 04:00.0) for PCI,
and by vendor:product ID for USB (not bus/device number, which isn't
stable across reconnects/reboots — note this means two USB devices sharing
the same VID:PID can't currently be told apart).
ToDO
Detaching hardware from a VM back to the host
Removing a passthrough section from LuCI only removes the configuration — it does not by itself unbind the device back to its original driver. To do that, run on the router:
/etc/init.d/qemu-vms release_pci_passthrough <pci-passthrough section name>
/etc/init.d/qemu-vms release_usb_passthrough <usb-passthrough section name>
This rebinds the device (and, for PCI, every device sharing its IOMMU
group) to whatever driver it was using before qemu-vms first touched it.
Notes and caveats
- Changing
disk_buson an existing VM does not convert the disk image. A guest installed undervirtiogenerally won't boot underide/satawithout the right drivers already present (or vice versa); this option is for new installs or guests that never had virtio support to begin with (e.g. older Windows). - Custom QEMU arguments (
custom_arg) are appended to the command line as literal argv entries, not re-parsed by a shell — this is intentional: it lets you pass arbitrary flags without risking shell metacharacters in that field being interpreted as commands. - ttyd and VNC websocket ports must be reachable from your browser, same as any other port opened directly on the router — if you're behind a firewall/NAT/reverse-proxy that only forwards 80/443, plan accordingly.
- Saving VM/network/passthrough settings writes to UCI immediately but does not automatically restart the affected VM — you need to explicitly Restart it from the Status tab for changes to take effect.
License
GPL-3.0