QEMU/Options
This article describes some of the options useful for configuring QEMU virtual machines. For the most up to date options for the current QEMU install run man qemu at a terminal.
It is important to note that the command has changed from qemu to qemu-system-x86_64 to launch QEMU as a 64-bit virtual machine.
Display options
There are a few available options to specify the kind of display to use in QEMU.
-display sdl
- Display video output via SDL (usually in a separate graphics window).
-display curses
- Displays video output via curses.
-display none
- Do not display video output. This option is different than the-nographic
option. See the man page for more information.
-display gtk
- Display video output in a GTK window. This is probably the option most users are looking for.
-display vnc=127.0.0.1:<X>
- Start a VNC server on display X (accepts an argument (X) for the display number). Substitute X for the number of the display (0 will then listen on 5900, 1 on 5901, etc).
For example to have QEMU send the display to a GTK window add the following option to the list:
user $
-display gtk
Machine
-machine type=q35,accel=kvm
- Modern chipset (PCIe, AHCI, ...) and hardware virtualization acceleration
-object rng-random,id=rng0,filename=/dev/urandom -device virtio-rng-pci,rng=rng0
- Pass-through for host random number generator. Accelerates startup of e.g. Debian VMs because of missing entropy.
Processor
-cpu <CPU>
- Specify a processor architecture to emulate. To see a list of supported architectures, run: qemu-system-x86_64 -cpu ?
-cpu host
- (Recommended) Emulate the host processor.
-smp <NUMBER>
- Specify the number of cores the guest is permitted to use. The number can be higher than the available cores on the host system. Use-smp $(nproc)
to use all currently available cores.
RAM
-m MEMORY
- Specify the amount of memory (default: 128 MB). For instance: -m 256M (M stands for Megabyte, G for Gigabyte).
Hard drive
-hda IMAGE.img
- Set a virtual hard drive and use the specified image file for it.
-drive
- Advanced configuration of a virtual hard drive:
-device virtio-scsi-pci,id=scsi0 -drive file=/dev/your/block,if=none,format=raw,discard=unmap,aio=native,cache=none,id=someid -device scsi-hd,drive=someid,bus=scsi0.0
Very fast Virtio SCSI emulation for block discards (TRIM), native command queuing (NCQ). You need at least onevirtio-scsi
-controller and for each block device a-drive
and-device scsi-hd
pair.
-drive file=IMAGE.img,if=virtio
- Set a virtual VirtIO-BLK hard drive and use the specified image file for it.
-drive file=/dev/sdX#,cache=none,if=virtio
- Set a virtual VirtIO-BLK hard drive and use the specified partition for it.
-drive id=disk,file=IMAGE.img,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0
- Set emulation layer for an ICH-9 AHCI controller and use the specified image file for it. The AHCI emulation supports NCQ, so multiple read or write requests can be outstanding at the same time.
Optical drives
-cdrom IMAGE.iso
- Set a virtual CDROM drive and use the specified image file for it.
-cdrom /dev/cdrom
- Set a virtual CDROM drive and use the host drive for it.
-drive
- Advanced configuration of a virtual CDROM drive:
-drive file=IMAGE.iso,media=cdrom
- Set a virtual CDROM drive and use the specified image file for it. With this syntax you can set multiple drives.
Boot order
-boot c
- Boot the first virtual hard drive.
-boot d
- Boot the first virtual CD-ROM drive.
-boot n
- Boot from virtual network.
Graphics card
QEMU can emulate several graphics cards:
-vga cirrus
- Simple graphics card. Every guest OS has a built-in driver.
-vga std
- Support resolutions >= 1280x1024x16. Linux, Windows XP and newer guest have a built-in driver.
-vga vmware
- VMware SVGA-II, more powerful graphics card. Install x11-drivers/xf86-video-vmware in Linux guests, VMware Tools in Windows XP and newer guests.
-vga qxl
- More powerful graphics card for use with SPICE.
To get more performance use the same color depth for your host as you use in the guest.
Guest screen resolutions greater than 1920x1024
The default graphics memory for clients is insufficient to be able to run with higher resolutions (eg 4K). In order to overcome this restriction, add the following device option to the command line:
user $
qemu-system-x86_64 -device VGA,vgamem_mb=64 ...
Once inside the desktop on the client, the higher screen resolutions should be available to select and save.
PCI pass-through
Device Drivers --->
[*] IOMMU Hardware Support --->
[*] Support for Intel IOMMU using DMA Remapping Devices
Bus options (PCI etc.) --->
<M> PCI Stub driver
Device Drivers --->
[*] IOMMU Hardware Support --->
[*] AMD IOMMU support
<M> AMD IOMMU Version 2 driver
Bus options (PCI etc.) --->
<M> PCI Stub driver
Find the host PCI device:
root #
lspci -nn
00:1b.0 Audio device [0403]: Intel Corporation 82801H (ICH8 Family) HD Audio Controller [8086:284b] (rev 02)
Note down the device (00:1b.0) and vendor (8086:284b) ID.
Unbind it:
root #
echo "8086 284b" > /sys/bus/pci/drivers/pci-stub/new_id
root #
echo "0000:00:1b.0" > /sys/bus/pci/devices/0000:00:1b.0/driver/unbind
root #
echo "0000:00:1b.0" > /sys/bus/pci/drivers/pci-stub/bind
And bind it to guest:
-device pci-assign,host=00:1b.0
Networking
Default - without any -netdev
option - is Pass-through.
Pass-through method only works for TCP and UDP connections.
Thus, ping is not a suitable tool to test networking connectivity because it uses ICMP.
Try using curl or other UDP or TCP/IP software for testing.Pass-through
-netdev user
- The QEMU process will create TCP and UDP connections for each connection in the VM. The virtual machine does not have an address reachable from the outside.
-device virtio-net,netdev=vmnic -netdev user,id=vmnic
- (Recommended) Pass-through with VirtIO support.
-netdev user,id=vmnic,hostfwd=tcp:127.0.0.1:9001-:22
- Let QEMU listen on port 9001. Connections to that port will be relayed to the VM on port 22.ssh -p 9001 localhost
will thus log into the VM.
Virtual network cable (TAP)
-device virtio-net,netdev=vmnic -netdev tap,id=vmnic,ifname=vnet0,script=no,downscript=no
- A new device (vnet0
) is created by QEMU on the host, the other end of the "cable" is at the VM.
MACVTAP
Example: one physical device, eno1
. Goal is to get two network devices, macvtap0
for
the host configured with DHCP, macvtap1
for the guest with configuration
inside the guest. If the guest uses DHCP configured inside the guest, it gets it from the same router where the host gets it from.
For the router it looks like there are two different hosts.
The new tap* devices get the kvm
group so qemu can run as user.
Communication between host and guest needs the cable plugged into eno1
and the router
be up.
Configuration for systemd-networkd:
[NetDev]
Name=macvtap0
Kind=macvtap
[MACVTAP]
Mode=bridge
[NetDev]
Name=macvtap1
Kind=macvtap
[MACVTAP]
Mode=bridge
[Match]
Name=macvtap0
[Network]
DHCP=yes
[Match]
Name=macvtap1
[Link]
ActivationPolicy=up
[Match]
Name=eno1
[Network]
MACVTAP=macvtap0
MACVTAP=macvtap1
Configruation for udev to set group owner and permission on the tap devices:
KERNEL=="tap*", GROUP="kvm", MODE="0660"
-nic tap,model=virtio-net-pci,mac=$(cat /sys/class/net/macvtap1/address),fd=3 3<>/dev/tap$(cat /sys/class/net/macvtap1/ifindex)
Network bridge
With this setup, we create a TAP interface (see above) and connect it to a virtual switch (the bridge).
Please first read about network bridging and QEMU about configuring kernel to support bridging.
OpenRC
Assuming a simple case with only one Virtual Machine with tap0 net interface and only one net interface on host with eth0.
# Bridge setup
tuntap_tap0="tap"
config_tap0="null"
config_eth0="null"
bridge_br0="eth0 tap0"
# Bridge static config
config_br0="10.0.42.1 netmask 255.255.255.0"
routes_br0="default via 10.0.42.100"
bridge_forward_delay_br0=0
bridge_hello_time_br0=1000
depend_br0() {
need net.eth0
need net.tap0
}
Host and guest can be on the same subnet. Configuration based on this forum post. [1]
systemd
Create the bridge:
[NetDev]
Name=vmbridge
Kind=bridge
Configure the bridge's address:
[Match]
Name=vmbridge
[Network]
Description=Your awesome VM bridge
Address=10.0.42.1/24
#!/usr/bin/env bash
# Bring the QEMU TAP device up and add it to the bridge
ip link set "$1" master vmbridge
ip link set "$1" up
After configuration of OpenRC or systemd, now we can run VM with the TAP networking option:
-device virtio-net-pci,netdev=n0,mac=13:37:yourchoice:42 -netdev tap,id=n0,ifname=vmtap,script=/your/path/to/qemu/stuff/addtobridge.sh,downscript=no
When the VM boots, the script will add the newly created device to the bridge. When you start another VM, both devices are in the bridge and the VMs can communicate with each other.
To successfully run VM you need permission for configure /dev/net/tun
NAT
A more advanced networking concept is outlined below, which enables guest access to an external network and also works with both wired and wireless adapters on the host. If desired, a DHCP server can also be setup on the host to allow for dynamic guest IP configurations. There are many different tutorials available online to further understand these concepts.[2][3][4][5][6]
Required packages
This example networking configuration needs some extra software installed:
root #
emerge --ask net-firewall/iptables
Host configuration
Creating TUN/TAP device
This allows the guest to communicate with the bridge. QEMU's default group is kvm
, ensure that the correct group is given permissions to control the TAP. Enabling promiscuous mode (promisc
) for the adapter might be unnecessary.
root #
ip tuntap add dev tap0 mode tap group kvm
root #
ip link set dev tap0 up promisc on
root #
ip addr add 0.0.0.0 dev tap0
Create network bridge
Creating a network bridge seems necessary, even if only 1 guest is configured. Create the bridge and add each TAP to it. Spanning tree protocol (stp
) is disabled because there is only 1 bridge.[7]
root #
ip link add br0 type bridge
root #
ip link set br0 up
root #
ip link set tap0 master br0
root #
echo 0 > /sys/class/net/br0/bridge/stp_state
root #
ip addr add 10.0.1.1/24 dev br0
Packet forwarding and NAT
Allows for proper packet routing (be sure to replace eth1
with an appropriate network interface name):
root #
sysctl net.ipv4.conf.tap0.proxy_arp=1
root #
sysctl net.ipv4.conf.eth1.proxy_arp=1
root #
sysctl net.ipv4.ip_forward=1
root #
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
root #
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
root #
iptables -A FORWARD -i br0 -o eth1 -j ACCEPT
Guest configuration
The following should be added to the configuration:
-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no
or, with QEMU 2.12.0 or newer:
-nic tap,ifname=tap0,script=no,downscript=no
After starting the guest, the IP should be configured to be on the vlan and the gateway should be the IP given to the bridge. The exact process will vary based on OS.
IPv6
For IPv6 networking see the IPv6 subarticle.
QEMU's built-in SMB server
This will only work if you are using Networking Pass-through
If the host system has a SMB server installed, QEMU can emulate a virtual SMB server for the guest system using the smb
attribute of -nic
optionː
-nic user,id=nic0,smb=/usr/local/public
- specify the folder to be shared, and it will be available to the guest as \\10.0.2.4\qemu.
Automatically generated smb.conf file located at /tmp/qemu-smb.pid-0/smb.conf
USB
-usbdevice tablet
- (Recommended) Use a USB tablet instead of the default PS/2 mouse. Recommend, because the tablet sends the mouse cursor's position to match the host mouse cursor.
-usbdevice host:VENDOR-ID:PRODUCT-ID
- Pass-through of a host USB device to the virtual machine. Determine with lsusb the device's vendor and product ID, e.g.:
user $
lsusb
Bus 001 Device 006: ID: 08ec:2039 M-Systems Flash Disk Pioneers
08ec
is the vendor ID,2039
is the product ID.
Keyboard layout
-k LAYOUT
- Set the keyboard layout, e.g. de for german keyboards. Recommend for VNC connections.
Snapshot
-snapshot
- Temporary snapshot: write all changes to temporary files instead of hard drive image.
-hda OVERLAY.img
- Overlay snapshot: write all changes to an overlay image instead of hard drive image. The original image is kept unmodified. To create the overlay image:
user $
qemu-img create -f qcow2 -b ORIGINAL.img OVERLAY.img