[Libguestfs] [PATCH libnbd] examples: Include an example of integrating with the glib main loop.

Richard W.M. Jones rjones at redhat.com
Wed Jul 17 12:48:03 UTC 2019


On Tue, Jul 16, 2019 at 10:24:24PM -0500, Eric Blake wrote:
> > +static gboolean
> > +prepare (GSource *sp, gint *timeout_)
> > +{
> > +  struct NBDSource *source = (struct NBDSource *) sp;
> > +
> > +  /* When the NBD handle moves out of the created state (which means
> > +   * that it first has a socket associated with it) we must initialize
> > +   * and register the pollfd.
> > +   */
> > +  if (!source->poll_registered && !nbd_aio_is_created (source->nbd)) {
> > +    int fd;
> > +
> > +    if (source->connecting_callback) {
> > +      DEBUG (source, "calling connecting_callback");
> > +      source->connecting_callback (source);
> > +    }
> 
> If I understand nbd_aio_connect_tcp properly, there are cases where we
> end up trying several options presented from getaddrinfo() with a
> possible reset back to START, at least until we get an fd that sticks.
> Does this need to take into account that an fd might change while still
> trying to do the initial connect?

Urgh yes, this is true.  There's a second problem which is that if the
connection becomes dead then the poll fd becomes invalid.  I think all
this can be solved but it involves some major reworking.  Still
working on it ...

> > +  /* Run the main loop until quit. */
> > +  g_main_loop_run (loop);
> > +  exit (EXIT_SUCCESS);
> 
> I guess the condition for causing the main loop to run is later on in
> one of the callbacks?

I think you meant to say "to quit"?  Yes, when we detect that the copy
has finished we call g_main_loop_quit in one of the callbacks.

> > +/* This callback is called from libnbd when any read command finishes. */
> > +static int
> > +finished_read (void *vp, int64_t cookie, int *error)
> > +{
> > +  size_t i;
> > +
> > +  if (gssrc == NULL)
> > +    return 0;
> > +
> > +  DEBUG (gssrc, "finished_read: read completed");
> > +
> > +  /* Find the corresponding buffer and mark it as completed. */
> > +  for (i = 0; i < nr_buffers; ++i) {
> > +    if (buffers[i].cookie == cookie)
> > +      goto found;
> > +  }
> > +  /* This should never happen. */
> > +  abort ();
> > +
> > + found:
> > +  buffers[i].state = BUFFER_READ_COMPLETED;
> 
> You asked on IRC if we should change the semantics of the *_callback
> variants to auto-retire the command (right now, the commands are not
> retired until nbd_aio_command_completed, but you can't call that from
> this callback because of the nbd handle lock - and calling it shouldn't
> reveal any more information than what you already have access to here).
> That may be a good idea to play with.

Yes, this is a problem still.

But at least I worked out why callbacks were (appearing to be) lost.
They aren't, but I was using the cookie to find the command in the
list of buffers.  Unfortunately I forgot that cookies are not unique
between libnbd handles ...

Rich.

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




More information about the Libguestfs mailing list