=head1 NAME

nbdkit-protocol - which parts of the NBD protocol nbdkit supports

=head1 SYNOPSIS

 nbdkit [-n|--newstyle] [--mask-handshake MASK] [--no-mc|--no-meta-contexts]
        [--no-sr|--no-structured-replies] [-o|--oldstyle] [...]

=head1 DESCRIPTION

This page documents the level of support in nbdkit for various parts
of the NBD protocol.

=head1 NEW STYLE VS OLD STYLE PROTOCOL

The NBD protocol comes in two incompatible forms that we call
"oldstyle" and "newstyle".  Unfortunately which protocol you should
use depends on the client and cannot be known in advance, nor can it
be negotiated from the server side.

nbdkit defaults to the newstyle protocol since nbdkit E<ge> 1.3 (the
command line flag I<-n> or I<--newstyle> is ignored for backwards
compatibility with older versions).  The newstyle protocol is better
in every respect than the oldstyle protocol and you should prefer it
if possible.  The newstyle protocol also includes extensions where a
client may request structured replies for even more capabilities, such
as sparse reads or meta contexts for obtaining block status.  By
default, nbdkit advertises as many features as it can support (in some
cases, this can be limited by what callbacks the plugin handles), even
if the client does not negotiate to use all advertised features.

Nbdkit also includes some options that are useful mainly when
performing integration tests, for proving whether clients have sane
fallback behavior when dealing various older servers permitted by the
NBD protocol.  The following options intentionally disable optional
parts of the NBD protocol, with successively larger impacts:

=over 4

=item B<--no-mc>

=item B<--no-meta-contexts>

Force the newstyle protocol to treat all requests for meta context
negotiation from the client as unsupported; the client will be unable
to query block status.  By default, nbdkit gracefully handles all meta
context requests, even though it currently supports only the
C<base:allocation> context (possibly by synthesizing a context that
represents an all-data disk when the plugin lacks support for
extents); but treating meta contexts as unsupported is useful for
emulating nbd-server 3.25.

=item B<--no-sr>

=item B<--no-structured-replies>

Force the newstyle protocol to decline any client request for
structured replies; this is stronger than I<--no-meta-contexts> in
that it also disables the opportunity for sparse reads.  This is
useful for emulating nbd-server 3.24.

=item B<--mask-handshake=>MASK

Alter the mask of which particular global features are advertised
during new-style handshake (defaulting to all supported bits set).
Clearing bit 0 (the low order bit) limits a client to using just
C<NBD_OPT_EXPORT_NAME> (incompatible with TLS, and includes all
effects of I<--no-sr>); clearing bit 1 causes the handshake to send
more padding bytes in response to C<NBD_OPT_EXPORT_NAME>.  Other bits
in the mask will only have an effect if the NBD protocol is extended
in the future to define other global bits.

=item B<-o>

=item B<--oldstyle>

Force the oldstyle protocol.  In this mode, I<--no-meta-contexts>,
I<--no-sr> and I<--mask-handshake> have no effect.

=back

=head2 Common clients and the protocol they require

 Client                          Protocol
 ------------------------------------------------------------
 qemu <= 2.5 without exportname  oldstyle
 qemu <= 2.5 with exportname     newstyle
 qemu >= 2.6                     client can talk either protocol
 qemu >= 2.11                    client tries structured replies
 nbd-client < 3.10               client can talk either protocol
 nbd-client >= 3.10              newstyle, no structured replies
 any TLS (encrypted) client      newstyle
 nbdkit nbd plugin               client can talk either protocol
 nbdkit >= 1.13.3                nbd plugin tries structured replies
 libnbd                          either protocol, tries structured replies

=head2 Errors seen if using the wrong protocol

If you use qemu E<le> 2.5 without the exportname field against a
newstyle server, it will give the error:

 Server requires an export name

If you use qemu E<le> 2.5 with the exportname field against an
oldstyle server, it will give the error:

 Server does not support export names

If you use the oldstyle protocol with nbd-client E<ge> 3.10, it will
give the error:

 Error: It looks like you're trying to connect to an oldstyle server.

=head2 NBD protocol and port number

Port 10809/tcp is reserved by IANA for the NBD protocol, but you can
use nbdkit on any port or on Unix domain sockets.

The NBD protocol specification claims that you should always use
newstyle when using port 10809, and use oldstyle on all other ports,
but this claim is not based on the reality of what NBD servers do, and
nbdkit does not require or encourage this.

=head1 NBD PROTOCOL FEATURES SUPPORTED BY NBDKIT

=over 4

=item newstyle protocol

Supported in nbdkit E<ge> 1.1.12, and the default in nbdkit E<ge> 1.3.

=item export names

Partially supported in nbdkit E<ge> 1.1.12.  Support for plugins to
read the client export name added in nbdkit E<ge> 1.15.2.

Versions of nbdkit before 1.16 could advertise a single export name to
clients, via a now deprecated side effect of the I<-e> option.  In
nbdkit 1.15.2, plugins could read the client requested export name
using L<nbdkit_export_name(3)> and serve different content.  In nbdkit
1.21.22, plugins could implement C<.list_exports> to answer
C<NBD_OPT_LIST> queries.

=item C<NBD_FLAG_NO_ZEROES>

Supported in nbdkit E<ge> 1.1.13.

This protocol optimization avoids sending a useless block of zero
bytes during protocol negotiation.

=item C<NBD_CMD_WRITE_ZEROES>

Supported in nbdkit E<ge> 1.1.13.

=item TLS with X.509 certificates

Supported in nbdkit E<ge> 1.1.15.

=item TLS with Pre-Shared Keys (PSK)

Supported in nbdkit E<ge> 1.4.0.

=item C<NBD_OPT_GO>

Supported in nbdkit E<ge> 1.5.3.

This protocol enhancement allows the server to return errors when
negotiating the export name.

=item C<NBD_OPT_INFO>

Supported in nbdkit E<ge> 1.9.3.

This protocol enhancement allows a client to inspect details about
the export without actually connecting.

=item C<NBD_FLAG_CAN_MULTI_CONN>

Supported in nbdkit E<ge> 1.9.9.

=item Structured Replies

Supported in nbdkit E<ge> 1.11.8.

However we don’t expose the capability to send structured replies to
plugins yet, nor do we send human-readable error messages using this
facility.

In nbdkit E<ge> 1.13.9, the command-line option I<--no-sr> can be used
to disable server support for structured replies, for testing client
fallbacks; disabling structured replies also disables features like
block status queries that depend on structured replies.

=item Metadata Querying

Supported in nbdkit E<ge> 1.11.8.

In nbdkit E<ge> 1.37.9, the command-line option I<--no-meta-contexts>
can be used to disable server support for meta contexts, for testing
client fallbacks.

=item Block Status

Supported in nbdkit E<ge> 1.11.10.

Only C<base:allocation> (ie. querying which parts of an image are
sparse) is supported.

Sparse reads (using C<NBD_REPLY_TYPE_OFFSET_HOLE> are not directly
supported, but a client can use block status to infer which portions
of the export do not need to be read.

=item C<NBD_FLAG_DF>

Supported in nbdkit E<ge> 1.11.11.

This protocol extension allows a client to force an all-or-none read
when structured replies are in effect. However, the flag is a no-op
until we extend the plugin API to allow a fragmented read in the first
place.

=item C<NBD_CMD_CACHE>

Supported in nbdkit E<ge> 1.13.4.

This protocol extension allows a client to inform the server about
intent to access a portion of the export, to allow the server an
opportunity to cache things appropriately.

=item C<NBD_CMD_FLAG_FAST_ZERO>

Supported in nbdkit E<ge> 1.15.0.

This protocol extension allows a server to advertise that it can rank
all zero requests as fast or slow, at which point the client can make
fast zero requests which fail immediately with C<ENOTSUP> if the
request is no faster than a counterpart write would be, while normal
zero requests still benefit from compressed network traffic regardless
of the time taken.

=item C<NBD_INFO_NAME>, C<NBD_INFO_DESCRIPTION>

Supported in nbdkit E<ge> 1.23.6.

These protocol extensions allow a client to learn more information
about an export during C<NBD_OPT_GO>.  The C<.default_export> callback
can inform a client of a canonical non-empty name in place of the
default export C<"">, and the C<.export_description> callback can give
a client more details about the export.

=item C<NBD_INFO_BLOCK_SIZE>

Supported in nbdkit E<ge> 1.30.

=item Resize Extension

I<Not supported>.

=item Extended Headers Extension

I<Not supported>.

=back

=head1 EXPORT-SAFE FILTERS

When a plugin supports NBD export names, it may serve different
content (eg. different disk images) on each export.  Some nbdkit
filters do not work properly in this case.

 Filter                  Export safe?

   blocksize               Yes
   blocksize-policy        Yes
   bzip2                   No
   cache                   No
   checkwrite              Yes
   count                   Yes
   cow                     Yes, since 1.44
   delay                   Yes
   error                   Yes
   evil                    Yes

   exitlast                Yes
   exitwhen                Yes
   exportname              Yes
   ext2                    No
   extentlist              Not useful with exports
   fua                     Yes
   gzip                    No
   ip                      Yes
   limit                   Yes
   log                     Yes

   luks                    No
   lzip                    No
   multi-conn              Yes
   nocache                 Yes
   noextents               Yes
   nofilter                Yes
   noparallel              Yes
   nozero                  Yes
   offset                  Yes, but unlikely to be useful
   openonce                Yes

   partition               No
   pause                   Yes
   protect                 Yes, but unlikely to be useful
   qcow2dec                No
   rate                    Yes
   readahead               Yes, since 1.32
   readonly                Yes
   retry                   Yes
   retry-request           Yes
   rotational              Yes

   scan                    Yes
   spinning                Yes
   stats                   Yes
   swab                    Yes
   tar                     No
   time-limit              Yes
   tls-fallback            Yes
   truncate                Yes, but unlikely to be useful
   xz                      No

=head1 SEE ALSO

L<nbdkit(1)>,
L<https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md>,
L<https://nbd.sourceforge.io/>.

=head1 AUTHORS

Eric Blake

Richard W.M. Jones

Pino Toscano

=head1 COPYRIGHT

Copyright Red Hat
