[libvirt] Non-blocking virStreamRecv always returns -2 (EAGAIN)?

Daniel P. Berrange berrange at redhat.com
Thu Jan 24 09:43:27 UTC 2013


On Thu, Jan 24, 2013 at 10:14:33AM +0100, Michal Privoznik wrote:
> On 23.01.2013 17:41, John Eckersberg wrote:
> > I'm running the following test program, and it works as written with a
> > blocking stream.  Inside the guest I'm running:
> > 
> > [root at f17-minimal ~]# socat /usr/share/dict/words /dev/virtio-ports/org.libguestfs.channel.0
> > 
> > As expected on the client side, I get all the words dumped.  However if
> > I swap the virStreamNew lines and instead use the non-blocking stream,
> > the virStreamRecv call always returns -2.
> > 
> >>From http://libvirt.org/internals/rpc.html#apiclientdispatch, I see:
> > 
> >  When no thread is performing any RPC method call, or sending stream
> >  data there is still a need to monitor the socket for incoming I/O
> >  related to asynchronous events, or stream data receipt. For this task,
> >  a watch is registered with the event loop which triggers whenever the
> >  socket is readable. This watch is automatically disabled whenever any
> >  other thread grabs the buck, and re-enabled when the buck is released.
> > 
> > If I understand that correctly, shouldn't the watch be responsible for
> > reading the stream data in this case?  Or am I just completely missing
> > something?
> > 
> > -----
> > #include <libvirt.h>
> > 
> > int main()
> > {
> >     virConnectPtr conn;
> >     virDomainPtr dom;
> >     virStreamPtr st;
> >     char buf[1024+1];
> >     int got = 0;
> > 
> >     conn = virConnectOpen("qemu+ssh://root@localhost/system");
> >     dom = virDomainLookupByName(conn, "f17-minimal");
> >     /* st = virStreamNew(conn, VIR_STREAM_NONBLOCK); */
> >     st = virStreamNew(conn, 0);
> >     virDomainOpenChannel(dom, "org.libguestfs.channel.0", st, 0);
> > 
> >     while (1) {
> >         got = virStreamRecv(st, buf, 1024);
> > 
> >         switch (got) {
> >         case 0:
> >             goto finish;
> >         case -1:
> >             goto free;
> >         case -2:
> >             puts("Retrying");
> >             sleep(1);
> >             continue;
> >         }
> >             
> >         buf[got] = '\0';
> >         puts(buf);
> >     }
> >         
> > finish:
> >     virStreamFinish(st);
> > free:
> >     virStreamFree(st);        
> > 
> >     return 0;
> > }
> > 
> > --
> > libvir-list mailing list
> > libvir-list at redhat.com
> > https://www.redhat.com/mailman/listinfo/libvir-list
> > 
> 
> In order to use VIR_STREAM_NONBLOCK, you need to call
> virStreamEventAddCallback() which registers your stream in libvirtd
> event loop so data is sent to you as read from chardev's socket.
> However, you need a client event loop then. So the simple program should
> look like this [1].

Hmm, we ough tto have raised an error when he tried to create a stream
with non-blocking flag set, but no event loop registered.

> 1: http://pastebin.com/JffxfSmg

It is much better to include the code in your mail and not use pastebin
links on the list. When people find this mail in google in 6 months time,
chances are the pastebin link will be dead.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list