Hi,
I've started an effort to introduce a consistent object model to QEMU.
Today, every subsystem implements an ad-hoc object model. These object
models all have the same basic properties but do things in arbitrarily
different ways:
1) Factory interface for object creation
- Objects usually have names
- Construction properties for objects
2) Object properties
- Some have converged around QemuOpts
- Some support properties on at construction time
- Most objects don't support introspection of properties
3) Inheritance and Polymorphism
- Most use a vtable to implement inheritance and polymorphism
- Only works effectively for one level of inheritance
- Inconsistency around semantics of overloaded functions
- Sometimes the base object invokes the overloaded function and
implements additional behavior
netdev, block, chardev, fsdev, qdev, and displaystate are all examples
of ad-hoc object models. They all have their own implementations of the
above and their own command line/monitor syntaxes.
QOM is a unifying object model inspired by the GObject/GType system.
Here is a short description of the feature it supports or is intended to
support:
1) All objects derive from a common base object (Plug). Plug's support
properties that can be set/get with a Visitor. This means QMP can be
natively used to read/write object properties.
2) Properties have a type and flags associated with them. Properties
can be read-only, read-write, and locked.
3) Locked properties are read-only after realize.
4) Two special types of properties, plug<> and socket<> allow for a
type-safe way to create a directed graph of objects at run time. This
provides a consistent mechanism to create a tree of devices and to
associate backends with devices.
5) Single inheritance is supported with full polymorphism. Interfaces
are also supported which allows a restricted (Java-style) form of MI.
6) All types are registered through the same interface. Type modules
can be used to implement anything from new devices, buses, block/net
backends, or even entirely new types of backends. In the future, I
would like to support demand loading of modules to allow a small core of
QEMU to be loaded which then loads only the bits of code required to run
a guest.
It has a few key different from GObject:
1) GObject properties are implemented as GValues. GValues are variants
that are assumed to be immutable. A key requirement of QOM is that we
can use the Visitor framework for interacting with properties. This
allows for a richer expression of properties (specifically, complex
device state to be serialized as a property).
2) GObject properties are installed in the class. In order to support
things like multifunction devices, we really need to install properties
with the object so that we can have arrays of properties that are sized
from another property.
3) GTypes/GObjects are always heap allocated as discrete objects.
GObjects are also reference counted. In order to support object
composition, it's necessary to be able to initialize an object from an
existing piece of memory.
I'll follow up later in the week with some documentation on how the type
system works in more detail. A tree is available below that has the
current implementation:
http://repo.or.cz/w/qemu/aliguori.git/tree/qdev2
I'll be documenting the type system at:
http://wiki.qemu.org/Features/QOM
Regards,
Anthony Liguori