[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