[Libguestfs] [PATCH nbdkit 1/4] Add reflection plugin.
Richard W.M. Jones
rjones at redhat.com
Tue Sep 17 07:42:28 UTC 2019
On Mon, Sep 16, 2019 at 10:33:18AM -0500, Eric Blake wrote:
> Is it worth noting that the NBD protocol imposes a 4k limit on the
> export name, which would limit things to about a 3k disk image when
> using base64? (It looks like nbdkit does not currently enforce that
> limit -- maybe it should, but as a separate patch -- but even if we
> don't change that, you're still limited to finding a client willing to
> send an export name larger than the protocol permits)
Yes the documentation should say this, I will modify it (and an
equivalent change in libnbd).
As for nbdkit I did check the code actually before posting and my
impression is that it does enforce the limit to a little under
MAX_OPTION_LENGTH (4096) albeit a indirectly. Don't these lines limit
it?
https://github.com/libguestfs/nbdkit/blob/7822f8fd66f51c730c6b2dc61e1677b4b579e256/server/protocol-handshake-newstyle.c#L242
https://github.com/libguestfs/nbdkit/blob/7822f8fd66f51c730c6b2dc61e1677b4b579e256/server/protocol-handshake-newstyle.c#L272
https://github.com/libguestfs/nbdkit/blob/7822f8fd66f51c730c6b2dc61e1677b4b579e256/server/protocol-handshake-newstyle.c#L401
> > +The plugin only supports read-only access. To make the disk writable,
> > +add L<nbdkit-cow-filter(1)> on top.
> > +
> > +=head1 EXAMPLES
> > +
> > +Create a reflection disk. By setting the export name to C<"hello">
> > +when we open it, a virtual disk of only 5 bytes containing these
> > +characters is created. We then display the contents:
> > +
> > + $ nbdkit reflection mode=exportname
> > + $ nbdsh -u 'nbd://localhost/hello' -c - <<'EOF'
> > + size = h.get_size()
> > + print("size = %d" % size)
> > + buf = h.pread(size, 0)
> > + print("buf = %r" % buf)
> > + EOF
>
> This leaves nbdkit running as a background daemon after the fact. Is it
> worth implementing a new 'nbdkit --one-shot' flag that causes nbdkit to
> exit after the first client disconnects?
https://github.com/libguestfs/nbdkit/blob/7822f8fd66f51c730c6b2dc61e1677b4b579e256/TODO#L11
The problem is that some clients connect twice - libguestfs in
particular does this (because it runs qemu-img info first). That
makes implementing something which will be useful rather impractical,
and it's probably better to use captive nbdkit here.
This works better IMO:
$ nbdkit --exit-with-parent reflection mode=exportname &
$ nbdsh -u 'nbd://localhost/hello' -c - <<'EOF'
...
[...]
> > +=head1 SEE ALSO
> > +
> > +L<nbdkit(1)>,
> > +L<nbdkit-plugin(3)>,
> > +L<nbdkit-cow-filter(1)>,
> > +L<nbdkit-data-plugin(1)>,
> > +L<nbdkit-memory-plugin(1)/Preloading small amounts of data>.
>
> Except that nbdkit-memory-plugin points only to nbdkit-data-plugin, so
> is this link helping?
Hmmm true :-/ Will remove it.
> > +static int
> > +reflection_config (const char *key, const char *value)
> > +{
> > + if (strcmp (key, "mode") == 0) {
> > + if (strcasecmp (value, "exportname") == 0) {
>
> Do we want to be nice and allow 'export-name' as an [undocumented]
> alternative spelling?
OK.
> > + mode = MODE_EXPORTNAME;
> > + }
> > + else if (strcasecmp (value, "base64exportname") == 0) {
>
> similarly for 'base64-export-name'
OK.
>
> > +#define reflection_config_help \
> > + "mode=MODE Plugin mode."
> > +
>
> Worth listing the valid values of MODE, or the fact that this parameter
> is optional because it defaults to exportname?
OK.
> > +++ b/tests/test-reflection-base64.sh
>
> > +
> > +requires nbdsh --version
> > +# XXX This needs to test $PYTHON somehow.
> > +#requires python -c 'import base64'
>
> Not just any python, but the version of python hard-coded as what will
> run nbdsh (which may be different than the $PYTHON that nbdkit was
> compiled with). I'm not sure what to suggest, other than just:
>
> requires nbdsh -c 'import base64'
>
> which could, in fact, be a single test (no need to test if nbdsh
> --version works if nbdsh -c ... works).
Yes, that's a much better idea.
>
> > +
> > +export e sock
> > +for e in "" "test" "テスト" \
>
> Worth also testing '-n' or '\n' (two strings that caused problems with
> the sh plugin implementation) (here, and in the plaintext version)?
I see that you have implemented this for tests/test-export-name.c so I
will modify this test in the same way.
> > +
> > +# Test that it fails if the caller passes in non-base64 data. The
> > +# server drops the connection in this case so it's not very graceful
> > +# but we should at least get an nbd.Error and not something else.
> > +nbdsh -c '
> > +import os
> > +import sys
> > +
> > +h.set_export_name ("xyz")
> > +try:
> > + h.connect_unix (os.environ["sock"])
> > + # This should not happen.
> > + sys.exit (1)
> > +except nbd.Error as ex:
> > + sys.exit (0)
> > +# This should not happen.
> > +sys.exit (1)
>
> The test looks good. (Yeah, figuring out how to make it more graceful
> in the future might be nice, but that's not this patch's problem. I'm
> thinking that if a plugin's .open() fails, nbdkit could reply with
> NBD_REP_ERR_UNKNOWN or NBD_REP_ERR_INVALID, and then wait for the client
> to disconnect, rather than the current hard hangup initiated by the server)
Abrupt disconnection isn't very good here. I guess we have never
really thought before about .open failing.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
More information about the Libguestfs
mailing list