[Libguestfs] [nbdkit PATCH v2 4/6] plugins: Add new nbdkit_set_error() utility function
Richard W.M. Jones
rjones at redhat.com
Thu Jan 26 15:16:12 UTC 2017
On Thu, Jan 26, 2017 at 08:21:17AM -0600, Eric Blake wrote:
> On 01/26/2017 04:13 AM, Richard W.M. Jones wrote:
> > On Wed, Jan 25, 2017 at 08:42:34PM -0600, Eric Blake wrote:
> >> +eg. NULL or -1. If the call to C<nbdkit_set_error> is omitted, then
> >> +the value of C<errno> will be used instead.
> > [...]
> >> +/* Grab the appropriate error value.
> >> + */
> >> +static int
> >> +_get_error (void)
> >> +{
> >> + int err = errno;
> >> + int ret = tls_get_error ();
> >> +
> >> + if (!ret)
> >> + ret = err ? err : EIO;
> >> + return ret;
> >> +}
> >
> > I don't think we should use the implicit errno.
>
> Pre-patch:
>
> C plugins use implicit errno, with reasonable success - but it requires
> that the C plugins be careful to not corrupt errno during cleanup.
> Language binding plugins use implicit errno, which is almost always wrong.
>
> >
> > The reason is that we cannot be sure that errno is meaningful in
> > language bindings. A lot of code could run between (eg) a Perl plugin
> > seeing a system call fail, and that plugin callback returning to
> > nbdkit code, and any of that code might touch errno. Since some of
> > that code would be in the language interpreter, we cannot even be
> > careful about preserving errno along those paths.
>
> Indeed - so it is a pre-existing bug.
Hmm, good point. I forgot that we were using errno even before 19184d3e.
Well I guess the patch is OK in that case.
> > So I think if the caller didn't call nbdkit_set_errno, we should
> > assume no errno value is available for us to use.
>
> Completely avoiding errno will make little difference to language
> binding plugins (errors will now default to EIO instead of errno if
> nbdkit_set_error() was not called, but even that error is still almost
> always wrong); but it will be a regression in quality for existing C
> plugins that aren't retrofitted to call nbdkit_set_error() everywhere.
>
> How about this: we add a new boolean callback .errno_is_reliable(),
> which defaults to true if omitted. C plugins that don't implement the
> new callback will continue to use implicit errno, for backwards
> compatibility and no regression; such a plugin can avoid
> nbdkit_set_error (although using it won't hurt, and will make it so that
> an accidental errno corruption during cleanup no longer matters).
> Meanwhile, all of our language bindings will implement the callback (at
> the C binding level) to return false, so that they now ignore errno
> entirely. We don't need to expose an errno_is_reliable binding to any
> of the languages; it is a C-only callback. Then exposing
> nbdkit_set_error through the language bindings will allow plugins to
> finally have control (rather than a completely random errno pre-patch or
> a forced EIO post-patch).
>
> I'll respin a v3 along those lines.
It sounds like errno_is_reliable is an unknowable value. How would we
set it correctly for Perl (for example), in a way that would work for
all past and future Perl interpreters?
It looks like v2 will be fine, no need to respin ...
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
More information about the Libguestfs
mailing list