[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