This post is a short introduction to the QemuOpts API inside QEMU. This is part of a series, see the introduction for other pointers and additional information.
QemuOpts was introduced in 2009. It is a simple abstraction that handles two tasks:
- Parsing of config files and command-line options
- Storage of configuration options
The QemuOpts data model is pretty simple:
QemuOptsListcarries the list of all options belonging to a given config group. Each entity is represented by a
QemuOptsrepresents a set of key-value pairs. (Some of the code refers to that as a config group, but to avoid confusion with
QemuOptsList, I will call them config sections).
QemuOptis a single key=value pair.
Some config groups have multiple
QemuOpts structs (e.g.
“drive”, “object”, “device”, that represent multiple drives,
multiple objects, and multiple devices, respectively), while
others always have only one
QemuOpts struct (e.g. the “machine”
For example, the following command-line options:
-drive id=disk1,file=disk.raw,format=raw,if=ide \ -drive id=disk2,file=disk.qcow2,format=qcow2,if=virtio \ -machine usb=on -machine accel=kvm
are represented internally as:
QemuOpts supports a limited number of data types for option values:
- Boolean options
- Numbers (integers)
Strings are just used as-is, after the command-line or config file is parsed.
Note: On the command-line, options are separated by commas, but
commas inside option values can be escaped as
The QemuOpt parser accepts only “on” and “off” as values for this option.
Warning: note that this behavior is different from the QOM property parser. I plan to explore this in future posts.
Numbers are supposed to be unsigned 64-bit integers. However, the
code relies on the behavior of
strtoull() and does not
reject negative numbers. That means the parsed
might be converted to a signed integer later. For example, the
following command-line is not rejected by QEMU:
$ qemu-system-x86_64 -smp cpus=-18446744073709551615,cores=1,threads=1
I don’t know if there is existing code that requires negative numbers to be accepted by the QemuOpts parser. I assume it exists, so we couldn’t easily change the existing parsing rules without breaking existing code.
Sizes are represented internally as integers, but the parser accept suffixes like K, M, G, T.
qemu-system-x86_64 -m size=2G
is equivalent to:
qemu-system-x86_64 -m size=2048M
Working around the QemuOpts parsers
QEMU code sometimes uses tricks to avoid or work around the QemuOpts option value parsers:
Example 1: using the raw option value
It is possible to get the original raw option value as a string
qemu_opt_get(), even after it was already parsed. For
example, the code that handles memory options in QEMU does that,
to ensure a suffix-less number is interpreted as Mebibytes, not
Example 2: empty option name list
Some options do not use the QemuOpts value parsers at all, by not defining any option names in the QemuOptsList struct. In those cases, the option values are parsed and validated using different methods. Some examples:
This is a common pattern when options are translated to other data representations: mostly QOM properties or QAPI structs. I plan to explore this in a future blog post.
The following config groups use this method and do their own parsing/validation of config options: acpi, device, drive, machine, net, netdev, numa, object, smbios, tpmdev
The QemuOpts code is responsible for two tasks:
- Parsing command-line options and config files
- Storage of configuration options
This means sometimes config options are parsed by custom code and
converted to QemuOpts data structures. Storage of config options
inside QemuOpts allow the existing QEMU configuration to be
written to a file using the
-writeconfig command-line option.
The original commit introducing
-writeconfig describes it this way:
In theory you should be able to do:
qemu < machine config cmd line switches here > -writeconfig vm.cfg qemu -readconfig vm.cfg
In practice it will not work. Not all command line switches are converted to QemuOpts, so you’ll have to keep the not-yet converted ones on the second line. Also there might be bugs lurking which prevent even the converted ones from working correctly.
This has improved over the years, but the comment still applies today: most command-line options are converted to QemuOpts options, but not all of them.