[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC] Machine description as data

From: Anthony Liguori
Subject: Re: [Qemu-devel] [RFC] Machine description as data
Date: Wed, 11 Feb 2009 13:01:29 -0600
User-agent: Thunderbird (X11/20090105)

I think your approach is pretty sound.  A few observations:

1) obviously need to eliminate the code duplication

2) the new code should fit with the rest of QEMU stylistically

3) I'd prefer incremental vs. perfect so let's try to do as much refactoring that will be required before actually going the full 9 yards and implementing the config file.

4) we don't have to solve all problems all at once as long as we don't regress existing features


Anthony Liguori

Markus Armbruster wrote:
Sorry for the length of this memo.  I tried to make it as concise as I
could.  And there's working mock-up source code to go with it.

Configuration should be data

A QEMU machine (selected with -M) is described by a struct QEMUMachine.
Which contains almost nothing of interest.  Pretty much everything,
including all the buses and devices is instead created by the machine's
initialization function.

Init functions consider a plethora of ad hoc configuration parameters
set by command line options.  Plenty of stuff remains hard-coded all
the same.

Configuration should be data, not code.

A machine's buses and devices can be expressed as a device tree.  More
on that below.

The need for a configuration file

The command line is a rather odd place to define a virtual machine.
Command line is fine for manipulating a particular run of the machine,
but the machine description belongs into a configuration file.

Once configuration is data, we should be able to initialize it from a
configuration file with relative ease.

However, this memo is only about the *internal* representation of
configuration.  How we get there from a configuration file is a separate
question.  It's without doubt a relevant question, but I feel I need to
limit my scope to have a chance of getting anywhere.

The need for an abstract device interface

Currently, each virtual device is created, configured and initialized in
its own idiosyncratic way.  Some configuration is received as arguments,
some is passed in global variables.

This is workable as long as the machine is constructed by ad hoc init
function code.  The resulting init function tends to be quite a
hairball, though.

I'd like to propose an abstract device interface, so we can build a
machine from its (tree-structured) configuration using just this
interface.  Device idiosyncrasies are to be hidden in the driver code
behind the interface.

What I propose to do

A. Configuration as data

   Define an internal machine configuration data structure.  Needs to be
   sufficiently generic to be able to support even oddball machine
   types.  Make it a decorated tree, i.e. a tree of named nodes with
   named properties.

   Create an instance for a prototype machine type.  Make it a PC,
   because that's the easiest to test.

   Define an abstract device interface, initially covering just device
   configuration and initialization.

   Implement the device interface for the devices used by the prototype
   machine type.

   Do not break existing machine types here.  This means we need to keep
   legacy interfaces until their last user is gone (step B).  Could
   become somewhat messy in places for a while.

B. Convert all the existing machine configurations to data.

   This can and should be done incrementally, each machine by people who
   care and know about it.

   Clean up the legacy interfaces now unused, and any messes we made
   behind them.

C. Read (and maybe write) machine configuration

   The external format to use is debatable.  Compared to the rest of the
   task, its choice looks like detail to me, but I'm biased ;)

   Writing the data could be useful for debugging.

D. Command line options to modify the configuration tree

   If we want them.

E. Make legacy command line modify the configuration tree

   For compatibility.  This is my "favourite" part.

We need to start with A.  The other tasks are largely independent.

What I've already done

Show me the code, they say.  Find attached a working prototype of step
A.  It passes the "Linux boots" test for me.  I didn't bother to rebase
to current HEAD, happy do to that on request.

Instead of hacking up machine "pc", I created a new machine "pcdt".  I
took a number of shortcuts:

* I put the "pcdt" code into the new file dt.c, and copied code from
  pc.c there.  I could have avoided that by putting my code in pc.c
  instead.  Putting it in a new file helped me pick apart the pc.c
  hairball.  To be cleaned up.

* I copied code from net.c.  Trivial to fix, just give it external
  linkage there.

* I hard-coded the configuration tree in the wrong place (tree.c), out of

* I didn't implement all the devices of the "pc" original.  The devices
  I implemented might not support all existing command line options.

Notable qualities:

* Device drivers are cleanly separated from each other, and from the
  device-agnostic configuration code.

* Each driver specifies the configurable properties in a single place.

* Device configuration is gotten from the configuration tree, which is
  fully checked.  Unknown properties are rejected.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]