[Libvir] Making QEMU use the real internal driver API

Daniel Veillard veillard at redhat.com
Wed May 9 23:10:58 UTC 2007

On Mon, May 07, 2007 at 04:26:13PM +0100, Daniel P. Berrange wrote:
> So currently, as we all know, the QEMU driver is just a shim through to the
> QEMU daemon. Looking at the code for Rich's remote driver I quite like the
> way the remote driver / server works like, and don't like the ugliness of
> having the special case QEMU code in there. We always had a long term plan
> to try & make the QEMU driver fit into the regular driver API more cleanly
> but not really tackled it yet. Similarly we've periodically brought up the 
> idea of having asynchronous notifications of 'interesting' state changes 
> in the drivers, to eliminate the need for polling.
> After a little thinking I have an idea that may let us address both issues 
> in one go. Or to be more precise, put infrastructure in place to let us
> move closer to allowing async notiifcations.

sounds quite interesting, though I'm still a bit afraid of async notification
because except registering a file descriptor, I don't see a good way to link
in the client event loop and that's still someting I find a bit ugly and would
rather avoid.

[... discussion removed ...]

> Oh, and we need to make sure the QEMU driver is never activated locally,
> only when libvirt.so is being used as part of 'libvirtd'.
> So at a high level what I think we'd need to add to the internal driver
> API to make this possible is
> In driver.h:
>  typedef int (*virDrvStartup)(void);
>  typedef int (*virDrvShutdown)(void);
> Adding these to the 'virDriver' struct. Regular apps using libvirt.so
> would never trigger these APIs - they're only intended for the daemon,
> so I figure we'd have to private APIs in the libivrt.so  (but not in
> the libvirt.h)
>   __virStartup(void);
>   __virShutdown(void);
> Since these are only called by the daemon, we now conveniently also have
> a way to stop the QEMU driver being locally activated.

  That sounds reasonnable to me.

> Next up, event loops.

  urgh, that's the ugly part ...

> First, we don't want to mandate a particular impl
> of an event loop. If you get into the argument about QT vs GLib vs libevent
> and libvirt picks one, then you make it hard for libvirt to integrate with
> apps using the other. Second, we don't want to assume that 1 connection 
> == 1 file handle. We also don't want to assume that the number of file
> handles used by a driver stays the same over time. Basically we need to
> expect that any single driver connection will have zero or more file
> handles that it is interested in.


> The DBus library deals with this exact same issue & the solution is very
> simple. The app using the libvirt registers a callback which the internal
> driver than then use to (un)register file handles. 

  that's a reasonnabe way. I also like the idea of a synchronous function
allowing to synchronously check for an event like in the FAM API, but I

> So in src/internal.h we'd add methods for internal drivers to call to
> add / remove file handles to/from the event loop:
>   /* 
>    * @fd: the file handle on which the event occurred
>    * @event: bitset of one or more of POLLxxx constants from poll.h
>    * @opaque: data associated with 'fd'
>    *
>    * Return 0 to continue monitoring, -1 if an error occurred
>    * and the handle should no longer be monitored
>    */
>   typedef int (*virEventCallback)(int fd, int events, void *opaque);
>   /*
>    * @fd: the file handle to start monitoring
>    * @events: bitset of POLLxxx contants to monitor
>    * @cb: callback to invoke when an event ocurrs
>    * @opaque: data to pass into callback's opaque parameter
>    */
>   int virEventAddHandle(int fd, int events, virEventCallback cb, void *opaque);
>   /*
>    * @fd: the file handle to stop monitoring
>    */
>   int virEventRemoveHandle(int fd);

  I'm not too fond of directly referencing the poll.h values though it is POSIX

> And we'd also add methods for a user of libvirt to register an event loop
> implementation:
>    typedef int (*virEventAddHandleImpl)(int fd, int events, opaque);
>    typedef int (*virEventRemoveHandleImpl)(int fd);
>    void virEventInitialize(virEventAddHandleImpl add, virEventRemoveHandleImpl remove);
> If we want to add support for async events into the public API, then the
> virEventInitialize method could instead be in libvirt.h, and exported in
> the  libvirt.so. Otherwise we could mark it private __virEventInitialize
> in libvirt.so.  
> That I think should be enough to let us move QEMU into a regular style libvirt
> driver.

  In general that sounds really good. I would probably not push the event
API as public right now, especially until I have a clear understanding how
it would work when using a remote model and ideally remote will be in in the 
next verion ;-)
> NB, what follows now is a quick brain-dump - I'm not suggesting implementing 
> this yet - its really a rough idea of general architecture. We'd definitely
> want to prototype it in a test app before committing to something like this.
> There's also many many scenarios to be thought about  beyond just watching
> create/destroy events

  testing the APIs internally first would make mee feel better definitely :-)


Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
veillard at redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/

More information about the libvir-list mailing list