[Libguestfs] Libnbd asynchronous API with epoll

Richard W.M. Jones rjones at redhat.com
Sun Jul 9 14:22:36 UTC 2023


On Sun, Jul 09, 2023 at 11:01:47AM +0100, Richard W.M. Jones wrote:
> (Sorry for the late reply, was a bit involved in a qemu bug last week ...)
> 
> On Fri, Jul 07, 2023 at 08:58:50AM +0000, Tage Johansson wrote:
> > On 7/6/2023 7:06 PM, Nir Soffer wrote:
> > 
> > 
> >     - After calling for example aio_notify_read(3), can I know that the next
> >     reading from the file descriptor would block?
> > 
> >     No, you have to call again aio_get_direction() and poll again until the
> >     event happens.
> > 
> > 
> > Well, what I mean is:
> >
> > After calling aio_notify_read, if aio_get_direction returns
> > AIO_DIRECTION_READ or AIO_DIRECTION_BOTH, can I know that the
> > reading on the file descriptor actually blocked? Or might there be
> > cases when aio_notify_read returns and the next direction includes a
> > read and there is still more data to read on the file descriptor?
> 
> It's probably best to have a look at the generated code, but it works
> like this:
> 
> - aio_notify_read is the program telling libnbd that the socket is
>   readable.  ie. The socket won't block, one byte at least is
>   available to read.
> 
> - aio_get_direction is libnbd telling the program that we are in a
>   state where we are expecting to read or write (or either) to the
>   socket.
> 
> As an example, let's say we have just connected to the NBD server.  We
> expect the NBD server to send a magic string, here:
> 
>   https://gitlab.com/nbdkit/libnbd/-/blob/20dceca48623835c3e8a195ef4135cce5e33efba/generator/states-magic.c#L28
> 
> For example:
> 
>   $ nbdkit -s null
>   NBDMAGICIHAVEOPT     <- magic string sent by the server
> 
> But in this case let's say the server is slow to send the magic string.
> 
> The call to recv_into_rbuf -> h->sock->ops->recv -> recv returns
> EWOULDBLOCK (recv_into_rbuf returns 1).  Then we stay in the same
> state (MAGIC.RECV_MAGIC), and return to the main program.
> 
> At this point if the main program calls nbd_aio_get_direction it would
> return AIO_DIRECTION_READ.  We are expecting to read the socket next.
> A write on the socket is not possible in this state (so we will not
> return AIO_DIRECTION_BOTH).

... and to continue the thought:

If the program now detects that the socket is readable using
select/poll/epoll/etc, it can call nbd_aio_notify_read.  This
re-enters the state machine, reading from the socket, getting some
data (hopefully), and moving the state machine on until it blocks
again, at which point nbd_aio_notify_read returns.

Then you'd call nbd_aio_get_direction again to find out if we are
blocked expecting a read, write (or either), and the cycle continues.

Rich.

> I hope that's a bit clearer.
> 
> I'm not sure about the epoll question.  I haven't thought about it
> deeply, but it seems as if edge-triggered notification might be a
> problem, but you could keep track of this from the main program with
> an extra variable, turning edge-triggered into level-triggered.
> 
> Rich.
> 
> > 
> > I guess this is the case, but I must know or the client may hang unexpectedly.
> > 
> > 
> > Best regards,
> > 
> > Tage
> > 
> > 
> 
> > _______________________________________________
> > Libguestfs mailing list
> > Libguestfs at redhat.com
> > https://listman.redhat.com/mailman/listinfo/libguestfs
> 
> 
> -- 
> Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
> Read my programming and virtualization blog: http://rwmj.wordpress.com
> virt-builder quickly builds VMs from scratch
> http://libguestfs.org/virt-builder.1.html
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://listman.redhat.com/mailman/listinfo/libguestfs

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
nbdkit - Flexible, fast NBD server with plugins
https://gitlab.com/nbdkit/nbdkit


More information about the Libguestfs mailing list