On Thu, Aug 31, 2023 at 10:52:59AM +0100, Richard W.M. Jones wrote:
> > Other plugins (eg written in C) ignore or
> > only partially consume the buffer in pwrite all the time, and that's
> > never a problem.
>
> I don't understand.
>
>
https://libguestfs.org/nbdkit-plugin.3.html#pwrite
>
> """
> The callback must write the whole count bytes if it can. The NBD
> protocol doesn't allow partial writes (instead, these would be errors).
> If the whole count bytes was written successfully, the callback should
> return 0 to indicate there was no error.
>
> If there is an error (including a short write which couldn't be
> recovered from), .pwrite should call nbdkit_error with an error message,
> and nbdkit_set_error to record an appropriate error (unless errno is
> sufficient), then return -1.
> """
>
> How is it safe for a plugin (written in C) to *silently* throw away part
> of the data that the client wants written?
Plugins can do what they want and we have plugins which do discard
data, silently or otherwise:
https://gitlab.com/nbdkit/nbdkit/-/blob/c662932f2bc71b5879b6eb83c93478191...
https://gitlab.com/nbdkit/nbdkit/-/blob/c662932f2bc71b5879b6eb83c93478191...
https://gitlab.com/nbdkit/nbdkit/-/blob/c662932f2bc71b5879b6eb83c93478191...
> I agree consistency between sh and other plugins is good, but the
> "baseline" seems unfathomable to me. I probably don't understand it.
sh plugin is often used for testing where the data written doesn't
matter but we're interested in other metadata like what write calls
were issued, eg:
https://gitlab.com/nbdkit/libnbd/-/blob/c713529e9fd0641b2d73f764517b5f9c2...
I look at it as: the plugin decides HOW to process the bytes that the
client requested to write. A traditional plugin will store the data
so it can be read back later (in which case, failing to read all of
stdin better result in the plugin returning failure). But during
testing, a plugin can declare "I am a data sink; I don't care what
bytes you write, my behavior is to ignore them and focus on something
else" (for example, it can be convenient to throw out a quick sh
plugin that has a side effect of counting .pwrite calls). Such a
plugin is going to confuse any client that expects to read back what
it just wrote, but when you are testing the protocol with a client
that only sends writes (and doesn't even attempt to send read
commands, because it knows the writes aren't persistent), that is just
fine. In other words, as long as your plugin documents that writes
are not persistent, then returning success without draining stdin
should be acceptable; just the same as a C plugin .pwrite that ignores
the input buffer can still return success.
Of course, until newer nbdkit has propagated to systems we care about,
any unit tests using sh or eval plugins as a data sink still have to
inject 'cat >/dev/null' to drain stdin, in order to pass under heavy
load when EPIPE even happens in the first place (I was surprised at
how hard it is to lose the race and actually get an EPIPE message from
nbdkit talking to the sh plugin script on my machine).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:
qemu.org |
libguestfs.org