Re: [Libguestfs] [PATCH nbdkit 0/7] server: Implement NBD_FLAG_CAN_MULTI_CONN.

Eric Blake
2019-01-04T23:26:07Z

On 1/4/19 4:08 PM, Richard W.M. Jones wrote:
> First thing to say is that I need to do a *lot* more testing on this,
> so this is just an early peek.  In particular, although it passed
> ‘make check && make check-valgrind’ I have *not* tested it against
a
> multi-conn-aware client such as the Linux kernel >= 4.9.
>
> This implements NBD_FLAG_CAN_MULTI_CONN, described in the protocol doc
> as:
>
>   "NBD_FLAG_CAN_MULTI_CONN: Indicates that the server operates
>   entirely without cache, or that the cache it uses is shared among
>   all connections to the given device. In particular, if this flag is
>   present, then the effects of NBD_CMD_FLUSH and NBD_CMD_FLAG_FUA MUST
>   be visible across all connections when the server sends its reply to
>   that command to the client. In the absence of this flag, clients
>   SHOULD NOT multiplex their commands over more than one connection to
>   the export."
>
> This is necessary to support the Linux nbd client -C option.

Sounds promising. And reminds me that I have not even tried to implement
this option for qemu yet, but probably should.

>
> The only plugin which sets the flag so far is file.  The ocaml, sh and
> nbd plugins allow the flag to be controlled or passed through.
>
> Notable also is that the blocksize filter has to filter out this flag,
> because I'm not convinced that the bounce buffer is safe.  However I
> believe the other filters *are* safe (although not really certain
> about the fua filter, and the new cache filter is tricky too).
>
> My feeling is that we should set the flag unconditionally for all
> readonly connections, but I can think of nasty corner cases where it
> might not work.  We should most probably set it in all plugins that
> are readonly (eg. nbdkit-pattern-plugin).

Should the callback include a bool readonly parameter that lets the
filter/plugin know for sure whether it is answering the question on a
read-only connection vs. on a read-write connection, as the answer may
differ between those two?

Should we automatically set the bit for any plugin that has
fully-serialized operation but does not provide the callback?  That is,
if a plugin uses SERIALIZE_CONNECTIONS, you can never have multiple
clients at the same time anyways (so the flag is trivially ignorable - a
client can try to set up a second connection for speed, but it won't
help).  A plugin that uses SERIALIZE_ALL_REQUESTS is also trivially
supported - any flush request will complete (regardless of which
connected client made it) prior to any other client being able to make
progress on a request that would need to see the results of the flush.
Only when we get to SERIALIZE_REQUESTS or PARALLEL can we have the
situation where one client's request can outpace the flush operation in
another client.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org