On Mon, Dec 10, 2007 at 10:28:01AM +0200, Yuval Kashtan wrote:
> Hello All,
> Attached is a proposed patch which adds DBus support to QEMU. DBus is a
> standard message bus for linux (
> http://www.freedesktop.org/wiki/Software/dbus )
> The idea behind this is to allow for external programs such as controlling
> GUI or HyperVisors to communicate and control QEMU, in a standard manner.
> Although it is possible to connect to the monitor, an API is more standard,
> theres no need to parse texts and error messages, no internationalization
> problems and in general is a much better idea.
> 
> Implementation:
> This is done by creating a DBus server from QEMU which raise signals and act
> upon methods.
> Methods mainly implement same logic as the current command line options and
> monitor does.
> 
> How to use:
> To enable DBus support you'll have to add --enable-dbus when you execure
> configure script.
> Then when you execute QEMU, you'll have to add -dbus-service <service_name>
> where service_name follows the DBus naming convention ( xxx.xxx.xxx....)
> To support QEMU configuration through DBus,  you'll also have to add
> -dbus_configuration which will cause QEMU to wait until ConfigDone is called
> through the DBus interface. this allows external programs time to call DBus
> methods starting with Config_ which changes configuration (just as the CLI
> does) thus enabling invocation of QEMU without parameters (beside the DBus
> ones).
> With that, we have implemented a nice python script that reads VM's
> configuration from INI file.

Frankly this is complete & utter overkill. QEMU needs a configuration file
for machines, but writing a configuration file in an external app and then 
sending that over DBus to QEMU is just insane, when QEMU can simply implement
a config file directly. Spawning QEMU then just becomes 'qemu -config foo.cfg'
instead of a mass of DBus calls. Having QEMU do the config file directly
is also portable to all operating systems and simpler to maintain, and easier
to deploy since it does not mandate a depedancy on a message  bus.


> Currently support was added to all important CLI configuration and some
> online monitor functions (such as connecting and disconnecting usb devices).
> 
> configuration methods begins with Config_ prefix and monitor ones with
> Monitor_.
> For a complete list you can just execute qemu and connect with dbus-viewer
> to see what is supported.

The style of the DBus API does not make any sense & does not follow the common
recommended approach for dbus services. 

The idea of well-known bus names is that they are well-known. Passing in the
DBus well-known name as a --service command line arg is non-sensical because
then it ceases to be well-known since it can change at the whim of the app /
admin running QEMU. 

Simply exporting a single object having populating that with a flat set of
methods mapping 1-1 onto the monitor commands is a bad idea. THis has been
done before and is very much unliked & discouraged (eg the Skype dbus control 
API which maps DBus methods straight onto the SKype monitor). The idea with
DBus is to provide a tree of objects mapping to objects managed within the
application, and then provide contextually relevant methods. 

So for a virtual machine management application you might have a main manager
object (eg '/qemu/Manager') which provides a way to list virtual machines. Each
virtual machine might then be its own object (eg '/qemu/Machines/<name>'). From
a machine one might have methods to list devices, and add & remove devices. Each
device though would be an object '/qemu/Machines/<name>/Devices/<device>'. The
device objects would implement different interfaces depending on the type of
device being managed. eg, you might have a qemu.Device.Disk interface, a 
qemu.Device.USB interface, etc, etc, and each interface would have methods
relevant to that type of device.

Which dovetails into the next point - having a DBus API for a single VM is not
really much use. To be generally useful it needs to have a single DBus service
to control all virtual machines (ie QEMU instances). This implies that any DBus
service doesn't belong in the QEMU process itself.

You're now back to square one - the DBus control service needs to spawn QEMU
instances and talk to the QEMU monitor.

IMHO, the entire idea of bolting DBus into QEMU to provide a control API is
just fundamentally flawed.



Looking at what you're trying to address I see two core problems

 - Interacting with QEMU at runtime to change various configs
 - Configuring QEMU at startup

For the first, we currently have the monitor. As you noted this is hard to
interact with programatically since it involves parsing & formating strings.
The way to deal with this problem is to provide a 'libqemumonitor.so' which
exposes a formal C api for the various runtime control needs. Internally
this library would talk to the monitor. This ensures that all the string
parsing & formatting is isolated in a single source, trivially usable by any 
application. Such a library would be easily cross-OS portable and not impose
unneccessary infrastructure on applications using it.

For the second problem of configuring QEMU, we're back at the often raised
point of QEMU needing a configuration file so applications don't need to build
up giant command line args.  Once QEMU had a configuration file, one might 
want to provide a library API  'libqemuconfig.so' to let both QEMU itself, and
applications using QEMU read and write the config files with well define APIs.
Again this is portable and does not impose unneccessary infrastructure.

One might even combine the libqemuconfig & libqemumonitor into a single 
general purpose  libqemucontrol.so library for apps to use.

> All the dbus handling routines can be found in dbus-monitor.c.
> I have two different implementations of this:
> 1) A single threaded version. which comply to the qemu standard of not
> opening additional threads.
> 2) A multi threaded version which open an additional, single, thread which
> handles all the DBus load. I actually believe this version is better as it
> allows QEMU to continue execution of guest operations even when there are
> DBus methods/signals to handle, whereas in the first option, DBus is
> integrated into QEMU mainloop. Also this makes it possible to monitor even
> during long operations (like monitoring the progress of savevm)

The multi-threaded version will be very hard todo safely. Any monitor command
would need to lock any data structures it touched from access by the main QEMU
thread to avoid data integrity issues. Likewise operations in the main thread
would need to lock data structures against the monitor. So you don't really
solve the problem you think you do. 

This question of single vs multi threaded again demonstrates to me that 
embedding
DBus in QEMU is the wrong solution.  If there is a need for a DBus control API
for QEMU, it needs to be higher up the stack, in a separate QEMU management 
service independant of the main QEMU emulator processses.  I've written such a
DBus api in the past - see the 'perl-QEMU-Manager' RPM here which provides a
DBus API for qemu written in Perl, and the 'qemu-admin' app which provides a
python GUI using the DBus API:

  http://people.redhat.com/berrange/olpc/sdk/SRPMS/

Since writing that code though, I came to the conclusion the idea was flawed in
many ways. Using DBus was one flaw. Targetting only QEMU was the second. Instead
I now work on libvirt which provides a formal C API for controlling virtual 
machines,
one which is able to support QEMU, Xen, KVM, etc, etc. So any GUI management app
can work with any virtualization technology.

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 


Reply via email to