[libvirt] Domain Event Handlers

Daniel Veillard veillard at redhat.com
Mon May 18 14:16:52 UTC 2009


On Mon, May 18, 2009 at 01:54:28PM +0100, Daniel P. Berrange wrote:
> On Mon, May 18, 2009 at 01:25:35PM +0100, Daniel P. Berrange wrote:
> > On Thu, May 14, 2009 at 06:43:10PM -0700, Noah Zoschke wrote:
> > > Hello,
> > > 
> > > I have been playing around with the libvirt domain event handlers in  
> > > Python and am seeing something surprising. I am using trunk libvirt  
> > > and `event-test.py` with some more of the debugging strings uncommented.
> > > 
> > > When I trigger my first event:
> > 
> > [snip]
> > 
> > > So my handler is always one event behind.
> > > 
> > > This behavior is not intended is it? Am I missing either something in  
> > > `event-test.py` or in how I am using virsh that would correct this  
> > > behavior?
> > 
> > This is not intended behaviour.  I have verified that I see the same
> > problem when running the event-test.py demo program. The C based
> > example  event-test.c  does work correctly. So either this is a bug
> > in the python demo program, or a bug in the python APIs for events.
> > Not sure which yet...
> 
> The demo program is horribly broken wrt handling timeouts
> 
> Also the python binding was not incrementing the ref count on
> the domain objects it was wrapping.
> 
> Daniel
> 
> diff -r 08f3de2814fb examples/domain-events/events-python/event-test.py
> --- a/examples/domain-events/events-python/event-test.py	Mon May 18 13:15:33 2009 +0100
> +++ b/examples/domain-events/events-python/event-test.py	Mon May 18 13:53:59 2009 +0100
> @@ -6,6 +6,8 @@ import select
>  mypoll = select.poll()
>  TIMEOUT_MS = 1000
>  
> +debug = False
> +
>  # handle globals
>  h_fd       = 0
>  h_events   = 0
> @@ -66,8 +68,9 @@ def myPollEventToEventHandleType(events)
>      return ret;
>  
>  def myAddHandle(fd, events, cb, opaque):
> -    global h_fd, h_events, h_cb, h_opaque
> -    #print "Adding Handle %s %s %s %s" % (str(fd), str(events), str(cb), str(opaque))
> +    global h_fd, h_events, h_cb, h_opaque, debug
> +    if debug:
> +        print "Adding Handle %s %s %s %s" % (str(fd), str(events), str(cb), str(opaque))
>      h_fd = fd
>      h_events = events
>      h_cb = cb
> @@ -76,36 +79,48 @@ def myAddHandle(fd, events, cb, opaque):
>      return 0
>  
>  def myUpdateHandle(watch, event):
> -    global h_fd, h_events
> -    #print "Updating Handle %s %s" % (str(h_fd), str(event))
> +    global h_fd, h_events, debug
> +    if debug:
> +        print "Updating Handle %s %s" % (str(h_fd), str(event))
>      h_events = event
>      mypoll.unregister(h_fd)
>      mypoll.register(h_fd, myEventHandleTypeToPollEvent(event))
>  
>  def myRemoveHandle(watch):
> -    global h_fd
> -    #print "Removing Handle %s" % str(h_fd)
> +    global h_fd, debug
> +    if debug:
> +        print "Removing Handle %s" % str(h_fd)
>      mypoll.unregister(h_fd)
>      h_fd = 0
>      return h_opaque
>  
>  def myAddTimeout(timeout, cb, opaque):
> -    global t_active, t_timeout, t_cb, t_opaque
> -    #print "Adding Timeout %s %s %s" % (str(timeout), str(cb), str(opaque))
> -    t_active = 1;
> +    global t_active, t_timeout, t_cb, t_opaque, debug
> +    if debug:
> +        print "Adding Timeout %s %s %s" % (str(timeout), str(cb), str(opaque))
> +    if timeout == -1:
> +        t_active = 0
> +    else:
> +        t_active = 1
>      t_timeout = timeout;
>      t_cb = cb;
>      t_opaque = opaque;
>      return 0
>  
>  def myUpdateTimeout(timer, timeout):
> -    global t_timeout
> -    #print "Updating Timeout %s %s" % (str(timer), str(timeout))
> +    global t_timeout, t_active, debug
> +    if debug:
> +        print "Updating Timeout %s %s" % (str(timer), str(timeout))
> +    if timeout == -1:
> +        t_active = 0
> +    else:
> +        t_active = 1
>      t_timeout = timeout;
>  
>  def myRemoveTimeout(timer):
> -    global t_active
> -    #print "Removing Timeout %s" % str(timer)
> +    global t_active, debug
> +    if debug:
> +        print "Removing Timeout %s" % str(timer)
>      t_active = 0;
>      return t_opaque
>  
> @@ -159,6 +174,8 @@ def main():
>  
>      while 1:
>          try:
> +            if debug:
> +                print "Poll sleep %d" % t_active
>              sts = mypoll.poll(TIMEOUT_MS)
>          except select.error, err:
>              if err[0] == errno.EINTR:
> @@ -168,17 +185,19 @@ def main():
>              print "Keyboard Interrupt caught - exiting cleanly"
>              break
>  
> +        if t_cb and t_active == 1:
> +            if debug:
> +                print "Invoking Timeout CB"
> +            t_cb(t_timeout, t_opaque[0], t_opaque[1])
> +
>          if not sts:
> -            #print "Timed out"
> +            if debug:
> +                print "Timed out"
>              continue
>  
>          rfd = sts[0][0]
>          revents = sts[0][1]
>  
> -        if t_active:
> -            #print "Invoking Timeout CB"
> -            t_cb(t_timeout, t_opaque[0], t_opaque[1])
> -
>          if revents & select.POLLHUP:
>              print "Reset by peer";
>              return -1;
> diff -r 08f3de2814fb python/libvir.c
> --- a/python/libvir.c	Mon May 18 13:15:33 2009 +0100
> +++ b/python/libvir.c	Mon May 18 13:53:59 2009 +0100
> @@ -1653,6 +1653,7 @@ libvirt_virConnectDomainEventCallback(vi
>      LIBVIRT_ENSURE_THREAD_STATE;
>  
>      /* Create a python instance of this virDomainPtr */
> +    virDomainRef(dom);
>      pyobj_dom = libvirt_virDomainPtrWrap(dom);
>      pyobj_dom_args = PyTuple_New(2);
>      if(PyTuple_SetItem(pyobj_dom_args, 0, pyobj_conn_inst)!=0) {

  ACK, looks fine to me,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list