backend: Rework internal error return semantics
commit1c70af75470228a9b7c0013e2da03fa61f1ef500
authorEric Blake <eblake@redhat.com>
Sun, 28 Jan 2018 02:31:35 +0000 (27 20:31 -0600)
committerEric Blake <eblake@redhat.com>
Thu, 22 Mar 2018 12:29:36 +0000 (22 07:29 -0500)
treed0d292e373151999d81c73e57efed11aaeb5c9d9
parent7a38586201d8dc81a046ad55f0027b6280c9346f
backend: Rework internal error return semantics

Previously, we let a plugin set an error in either thread-local
storage (nbdkit_set_error()) or errno, then connections.c would
decode which error to use.  But with filters in the mix, it is
very difficult for a filter to know what error was set by the
plugin (particularly since nbdkit_set_error() has no public
counterpart for reading the thread-local storage).  What's more,
if a filter does any non-trivial processing after calling into
next_ops, it is very probable that errno might be corrupted,
which would affect the error returned by a plugin that relied
on errno but not the error stored in thread-local storage.

Furthermore, in connections.c, handle_request() already has to
return a positive error value, as recv_request_send_reply()
then uses that value for determining what to send over the wire
to the client; so getting to the positive value sooner rather
than later can simplify the call stack.

We make the change in two steps: this patch changes the internal
interface to return the error value in a separate parameter,
and guarantees that filters see a valid value in errno; then a
later patch adjusts the public filter API to be more useful and
to more closely mirror the internal API.  The err parameter must
be set if the return is -1, and is ignored otherwise; for now,
it is only set by plugins.c (as the filter code needs to expose
it to the public filter callback API before it can be usefully
manipulated).  With the change in decoding location, the backend
interface no longer needs an .errno_is_preserved() callback.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/connections.c
src/filters.c
src/internal.h
src/plugins.c