[libvirt] RFC: Add further domain event callbacks

Daniel P. Berrange berrange at redhat.com
Tue Mar 16 10:54:33 UTC 2010


On Tue, Mar 16, 2010 at 11:16:43AM +0100, Daniel Veillard wrote:
> On Thu, Mar 04, 2010 at 03:25:28PM +0000, Daniel P. Berrange wrote:
> 
> > Option 2
> > --------
> > 
> > GLib/GObject take a very loosely typed approach to registering/unregistering
> > events. The have a single pair of methods that work for any event & a generic
> > callback signature, requiring application casts.
> > 
> >      typedef int (*virConnectEventCallback)(void *opaque);
> > 
> >     int virConnectEventRegister(virConnectPtr conn,
> >                                 const char *eventname,
> >                                 virConnectEventCallback cb,
> >                                 void *opaque,
> >                                 virFreeCallback freecb);
> > 
> >     int virCOnnectEventUnregister(virConnectPtr conn,
> >                                   int eventID);
> > 
> > In this model, the register method returns a unique integer ID for the 
> > callback which can be used to unregister it. Application's using this
> > will still need a strongly typed callback for receiving the event, but
> > when calling virConnectEventRegister(), the would do an explicit 'bad'
> > cast to 'virConnectEventCallback'
> 
>   That fine to me except that for example if you want to bind to a
> specific object (a domain, an interface) to catch his mutation, then
> you need to pass this too, ending up with
> 
>   int virConnectEventRegister(virConnectPtr conn,
>                               void * object,
>                               const char *eventname,
>                               virConnectEventCallback cb,
>                               void *opaque,
>                               virFreeCallback freecb);
> 
> that means two casts. I like the unregister based on the ID token
> though, that part can be completely generic.

We could still provide the register method against the domain object
directly

  int virDomainEventRegister(virDomainPtr dom,
                             const char *eventname,
                             virConnectEventCallback cb,
                             void *opaque,
                             virFreeCallback freecb);

We might end up having virStoragePoolEventRegister too, but that's
not soo bad, since its a fairly finite set of methods.

> That still doesn't solve the opaque callback object allocation, I'm
> afraid, unless libvirt itself doesn't touch anything, but then that
> mean that libvirt can only pass an event, but not provide any contextual
> information (any of the extra stuff we use for Domain callbacks).
> 
> 
> > 
> > Option 3
> > --------
> > 
> > A hybrid of both approaches. Have a new 'register' method for each type of
> > event that takes a strongly typed callback, but have a generic 'unregister'
> > method that just uses the 'int eventID'
> > 
> >    int virConnectDomainBlockIOEventRegister(virConnectPtr conn,
> >                                             virConnectDomainBlockIOEventCallback cb,
> >                                             void *opaque,
> >                                             virFreeCallback freecb);
> > 
> >    int virCOnnectEventUnregister(virConnectPtr conn,
> >                                   int eventID);
> > 
> > 
> 
>   Doesn't solve the real problem.
> 
> > Option 4
> > --------
> > 
> > Have one pair of register/unregister events, but instead of passing diffeerent
> > parameters to each callback, have a generic callback that takes a single
> > parameter. This parameter would be declared as a union. So depending on
> > the type of event being received, you'd access different parts of the union
> > 
> > 
> >     typedef union {
> >        virConnectDomainBlockIOEvent blockio;
> >        virConnectDomainWatchdogEvent watchdog;
> >        ...other events...
> >     } virConnectEvent;
> > 
> > 
> > Either we could include a dummy member in the union with padding  to 1024
> > bytes in size for future expansion, or we could simply declare that apps
> > must never allocate this data type themselves, thus allowing us to enlarge
> > it at will.
> 
>   yeah, I know that glib has been doing that padding to ensure forward
> compatibility over time. I find that a bit fishy. At least that solves
> the allocation problem for data passed by libvirt as part of the
> callback.
> 
> >     typedef int (*virConnectEventCallback)(int eventType, virConnectEvent, void *opaque);
> > 
> >     int virConnectEventRegister(virConnectPtr conn,
> >                                 const char *eventname,
> >                                 virConnectEventCallback cb,
> >                                 void *opaque,
> >                                 virFreeCallback freecb);
> > 
> >     int virConnectEventUnregister(virConnectPtr conn,
> >                                   int eventID);
> > 
> > 
> 
>   I'm undecided yet between 1/ 2/ and 4/ there are pros and cons to all
> of them in terms of API.
> 
> > There is one final question unrelated to these 4 options. For the lifecycle
> > events we always registered against the 'virConnectPtr' since that is 
> > needed to capture 'domain created' events where there's no virDomainPtr
> > to register a callback against yet.
> > 
> > Do we want to always register all events aganist the virConnectPtr, and
> > then pass a 'virDomainPtr' as a parameter to the callbacks as needed. Or
> 
>   yes I don't see how we could avoid adding an extra target object
> 
> > should we allow registering events against the virDomainPtr directly.
> > The latter might make it simpler to map libvirt into GLib/GObjects event
> > system in the future.
> 
>   Then IMHO in that case we're stuck with 1/ , if we have per target
> objects type of registrations, or as I suggested 2/ with an extra
> void *object

I think option 2/ would map most easily into the GLib/Qt event models, if
we registered directly against virDomainPtr instead of virConnectPtr+void*domain

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list