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

Michal Privoznik mprivozn at redhat.com
Thu Jan 24 09:14:33 UTC 2013


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].

Michal

1: http://pastebin.com/JffxfSmg




More information about the libvir-list mailing list