TT Lab
Get started
Learn Learning paths Courses

Virtualisation with QEMU/KVM

How to Read a QEMU Command Line

Continue in TT Lab

In one line

A QEMU command line is the parts list of the virtual hardware. Each flag decides a device the guest will see.

Why you need this

In practice you mostly use libvirt or a cloud console. But when a problem arises, you end up having to read the QEMU command line underneath. libvirt's XML is converted into this command line in the end too, and checking the actual launch arguments with ps aux | grep qemu is the first step of diagnosis.

How it works

A minimal VM looks like this.

qemu-system-x86_64 \
  -accel tcg \
  -m 512 \
  -smp 2 \
  -drive file=/root/vm/vm01.qcow2,if=virtio,format=qcow2 \
  -netdev user,id=n0,hostfwd=tcp::12222-:22 \
  -device virtio-net-pci,netdev=n0 \
  -nographic \
  -serial mon:stdio

The meaning of each flag.

Flag Meaning Practical point
-accel kvm / tcg Choose the accelerator Check what is available with -accel help
-m 512 Memory (MB) MB if the unit is omitted
-smp 2 Number of vCPUs You can specify the topology with -smp 2,sockets=1,cores=2
-drive ...,if=virtio Disk + interface It is safe to specify format= explicitly
-netdev / -device Backend / frontend The two always come as a pair
-nographic No graphics The default for server environments
-serial mon:stdio Serial on stdio, doubling as the monitor Switch with Ctrl-a c
-monitor unix:<경로>,server,nowait The monitor on a Unix socket (the placeholder is the socket path) Suited to automation

The separation of -netdev and -device is confusing at first. -netdev is the host-side backend (where do the packets go), and -device is the NIC the guest sees (what card does it appear as). You connect the two with id=.

Network modes

Mode Characteristics When
user (SLIRP) User-space NAT. No privileges needed Development/testing. The only choice in this lab environment
tap Kernel TAP device Production. Needs privileges
bridge Connect the TAP to a bridge Communication between VMs, external exposure
vhost-net Ring processing in the kernel High performance

In user mode the guest can go out, but nothing from the outside can come in to the guest. So you open a port with hostfwd.

-netdev user,id=n0,hostfwd=tcp::12222-:22

TCP arriving at the host's 12222 is sent to the guest's 22. This listening socket is opened the moment QEMU starts — it shows up in ss -ltn even while the guest is still booting. If the guest has not come up, the connection is merely refused.

The monitor

The QEMU monitor is a console for talking to the running VM.

-monitor unix:/root/vm/mon.sock,server,nowait
echo 'info status' | nc -U /root/vm/mon.sock
echo 'info block'  | nc -U /root/vm/mon.sock

There are commands such as info status (running/stopped), info block (disks), info network, system_powerdown (an ACPI shutdown request), and savevm/loadvm (snapshots while running). In automation, attaching by socket is the standard.

The console

You use a serial console with the combination of -nographic and -serial. You have to pass console=ttyS0 to the guest kernel for kernel messages to come out on the serial port. To keep the log in a file, use -serial file:/root/vm/console.log.

If you know the order of the things you see early in the boot, you can tell how far it has progressed.

  1. SeaBIOS (version ...) — the firmware is up
  2. Booting from Hard Disk... — it has handed over to the bootloader
  3. Linux version ... — the kernel has started
  4. The login prompt — it has reached user space

Item 1 appears as soon as QEMU starts. Even if it takes a long time to reach item 3 because of TCG, if you see items 1 and 2, the disk and the bootloader are fine.

What it looks like in the field

Check the actual arguments with ps aux | grep qemu. There are cases where libvirt's XML differs from the actual launch arguments (cached domain definitions, hotplugged devices). The truth is in the process command line.

Problems from omitting format=. QEMU guesses the format by looking at the file contents, and if the guest writes data that looks like a qcow2 header at the start of the disk, it may be misidentified at the next boot. Always specify it.

What you will do in the next lab

You create an overlay backed by an image in /opt/vm/, write a launch script with the exact flags, actually bring it up, and check three things: the serial log, the monitor response, and the hostfwd listening socket.