Hello community,

here is the log from the commit of package nbd for openSUSE:Factory checked in 
at 2020-03-25 23:41:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nbd (Old)
 and      /work/SRC/openSUSE:Factory/.nbd.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nbd"

Wed Mar 25 23:41:38 2020 rev:51 rq:786152 version:3.20

Changes:
--------
--- /work/SRC/openSUSE:Factory/nbd/nbd.changes  2019-06-12 13:04:36.689226130 
+0200
+++ /work/SRC/openSUSE:Factory/.nbd.new.3160/nbd.changes        2020-03-25 
23:41:41.131961986 +0100
@@ -1,0 +2,5 @@
+Wed Mar 18 10:36:55 UTC 2020 - Paolo Stivanin <i...@paolostivanin.com>
+
+- Update to 3.20.0 (no changelog)
+
+-------------------------------------------------------------------

Old:
----
  nbd-3.19.tar.xz

New:
----
  nbd-3.20.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nbd.spec ++++++
--- /var/tmp/diff_new_pack.ytjOuJ/_old  2020-03-25 23:41:41.735962184 +0100
+++ /var/tmp/diff_new_pack.ytjOuJ/_new  2020-03-25 23:41:41.739962185 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package nbd
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -25,7 +25,7 @@
 %define use_firewalld 0
 %endif
 Name:           nbd
-Version:        3.19
+Version:        3.20
 Release:        0
 Summary:        Network Block Device Server and Client Utilities
 License:        GPL-2.0-or-later
@@ -73,7 +73,7 @@
 
 %build
 %configure
-make %{?_smp_mflags}
+%make_build
 
 %install
 %make_install

++++++ nbd-3.19.tar.xz -> nbd-3.20.tar.xz ++++++
++++ 1648 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/cliserv.h new/nbd-3.20/cliserv.h
--- old/nbd-3.19/cliserv.h      2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/cliserv.h      2019-04-12 17:18:59.000000000 +0200
@@ -76,7 +76,8 @@
 void setmysockopt(int sock);
 void err_nonfatal(const char *s);
 
-void err(const char *s) G_GNUC_NORETURN;
+void nbd_err(const char *s) G_GNUC_NORETURN;
+#define err(S) nbd_err(S)
 
 void logging(const char* name);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/config.h.in new/nbd-3.20/config.h.in
--- old/nbd-3.19/config.h.in    2019-01-30 16:34:42.000000000 +0100
+++ new/nbd-3.20/config.h.in    2019-09-15 14:04:48.000000000 +0200
@@ -16,6 +16,9 @@
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #undef HAVE_ARPA_INET_H
 
+/* Define to 1 if you have the BLKDISCARD ioctl */
+#undef HAVE_BLKDISCARD
+
 /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
    */
 #undef HAVE_DIRENT_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/configure.ac new/nbd-3.20/configure.ac
--- old/nbd-3.19/configure.ac   2019-01-30 16:24:10.000000000 +0100
+++ new/nbd-3.20/configure.ac   2019-09-15 14:04:36.000000000 +0200
@@ -13,6 +13,7 @@
 ])
 AM_INIT_AUTOMAKE(foreign dist-xz serial_tests subdir-objects)
 AM_MAINTAINER_MODE([enable])
+AM_SILENT_RULES([yes])
 AC_CONFIG_MACRO_DIR([support])
 LT_INIT
 
@@ -142,6 +143,8 @@
        AC_MSG_RESULT([no])
 fi
 
+AC_CHECK_DECL([BLKDISCARD], AC_DEFINE(HAVE_BLKDISCARD, 1, [Define to 1 if you 
have the BLKDISCARD ioctl]), AC_DEFINE(HAVE_BLKDISCARD, 0), [#include 
<linux/fs.h>])
+
 AC_CHECK_FUNC(splice, [HAVE_SPLICE=yes], [HAVE_SPLICE=no])
 if test "$HAVE_SPLICE" = "yes"
 then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/doc/Makefile.am new/nbd-3.20/doc/Makefile.am
--- old/nbd-3.19/doc/Makefile.am        2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/doc/Makefile.am        2019-09-15 13:35:52.000000000 +0200
@@ -1 +1 @@
-EXTRA_DIST = README proto.md todo.txt
+EXTRA_DIST = README proto.md todo.txt uri.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/doc/proto.md new/nbd-3.20/doc/proto.md
--- old/nbd-3.19/doc/proto.md   2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/doc/proto.md   2019-09-15 13:35:52.000000000 +0200
@@ -64,6 +64,17 @@
 with the server during the handshake. This document does not describe
 those.
 
+When handling the client-side transmission phase with the Linux
+kernel, the socket between the client and server can use either Unix
+or TCP sockets. For other implementations, the client and server can
+use any agreeable communication channel (a socket is typical, but it
+is also possible to implement the NBD protocol over a pair of
+uni-directional pipes). If TCP sockets are used, both the client and
+server SHOULD disable Nagle's algorithm (that is, use `setsockopt` to
+set the `TCP_NODELAY` option to non-zero), to eliminate artificial
+delays caused by waiting for an ACK response when a large message
+payload spans multiple network packets.
+
 ### Handshake
 
 The handshake is the first phase of the protocol. Its main purpose is to
@@ -364,7 +375,7 @@
 `NBD_CMD_READ` are as follows.  First, it is not possible to support
 partial reads or early errors (the command must succeed or fail as a
 whole, and either *length* bytes of data must be sent or a hard disconnect
-must be initiated, even if the failure is `EINVAL` due to bad flags).
+must be initiated, even if the failure is `NBD_EINVAL` due to bad flags).
 Second, there is no way to efficiently skip over portions of a sparse
 file that are known to contain all zeroes.  Finally, it is not
 possible to reliably decode the server traffic without also having
@@ -378,7 +389,7 @@
 structured replies are negotiated, the server MUST use a
 structured reply for any response with a payload, and MUST NOT use
 a simple reply for `NBD_CMD_READ` (even for the case of an early
-`EINVAL` due to bad flags), but MAY use either a simple reply or a
+`NBD_EINVAL` due to bad flags), but MAY use either a simple reply or a
 structured reply to all other requests.  The server SHOULD prefer
 sending errors via a structured reply, as the error can then be
 accompanied by a string payload to present to a human user.
@@ -436,9 +447,9 @@
 requests to be serviced prior to initiating a hard disconnect.
 A server MAY speed this process up by issuing error replies.
 The error value issued in respect of these requests and
-any subsequently received requests SHOULD be `ESHUTDOWN`.
+any subsequently received requests SHOULD be `NBD_ESHUTDOWN`.
 
-If the client receives an `ESHUTDOWN` error it MUST initiate
+If the client receives an `NBD_ESHUTDOWN` error it MUST initiate
 a soft disconnect.
 
 The client MAY issue a soft disconnect at any time, but
@@ -806,7 +817,7 @@
 multiples of any advertised preferred block size where possible.  For
 those requests, the client MUST NOT use a *length* larger than any
 advertised maximum block size or which, when added to *offset*, would
-exceed the export size.  The server SHOULD report an `EINVAL` error if
+exceed the export size.  The server SHOULD report an `NBD_EINVAL` error if
 the client's request is not aligned to advertised minimum block size
 boundaries, or is larger than the advertised maximum block size.
 Notwithstanding any maximum block size advertised, either the server
@@ -818,7 +829,7 @@
 maximum block size is smaller).  For all other commands, where the
 *length* is not reflected in the payload (such as `NBD_CMD_TRIM` or
 `NBD_CMD_WRITE_ZEROES`), a server SHOULD merely fail the command with
-an `EINVAL` error for a client that exceeds the maximum block size,
+an `NBD_EINVAL` error for a client that exceeds the maximum block size,
 rather than initiating a hard disconnect.
 
 ## Metadata querying
@@ -864,7 +875,7 @@
 A client MUST NOT use `NBD_CMD_BLOCK_STATUS` unless it selected a
 nonzero number of metadata contexts during negotiation, and used the
 same export name for the subsequent `NBD_OPT_GO` (or
-`NBD_OPT_EXPORT_NAME`). Servers SHOULD reply with `EINVAL` to clients
+`NBD_OPT_EXPORT_NAME`). Servers SHOULD reply with `NBD_EINVAL` to clients
 sending `NBD_CMD_BLOCK_STATUS` without selecting at least one metadata
 context.
 
@@ -933,17 +944,17 @@
 metadata context. If an extent is marked with `NBD_STATE_HOLE` at that
 context, this means that the given extent is not allocated in the
 backend storage, and that writing to the extent MAY result in the
-`ENOSPC` error. This supports sparse file semantics on the server
+`NBD_ENOSPC` error. This supports sparse file semantics on the server
 side.  If a server supports the `base:allocation` metadata context,
 then writing to an extent which has `NBD_STATE_HOLE` clear MUST NOT
-fail with `ENOSPC` unless for reasons specified in the definition of
+fail with `NBD_ENOSPC` unless for reasons specified in the definition of
 another context.
 
 It defines the following flags for the flags field:
 
 - `NBD_STATE_HOLE` (bit 0): if set, the block represents a hole (and
   future writes to that area may cause fragmentation or encounter an
-  `ENOSPC` error); if clear, the block is allocated or the server
+  `NBD_ENOSPC` error); if clear, the block is allocated or the server
   could not otherwise determine its status. Note that the use of
   `NBD_CMD_TRIM` is related to this status, but that the server MAY
   report a hole even where `NBD_CMD_TRIM` has not been requested, and
@@ -1059,6 +1070,18 @@
   which support the command without advertising this bit, and
   conversely that this bit does not guarantee that the command will
   succeed or have an impact.
+- bit 11, `NBD_FLAG_SEND_FAST_ZERO`: allow clients to detect whether
+  `NBD_CMD_WRITE_ZEROES` is faster than a corresponding write. The
+  server MUST set this transmission flag to 1 if the
+  `NBD_CMD_WRITE_ZEROES` request supports the `NBD_CMD_FLAG_FAST_ZERO`
+  flag, and MUST set this transmission flag to 0 if
+  `NBD_FLAG_SEND_WRITE_ZEROES` is not set. Servers MAY set this this
+  transmission flag even if it will always use `NBD_ENOTSUP` failures for
+  requests with `NBD_CMD_FLAG_FAST_ZERO` set (such as if the server
+  cannot quickly determine whether a particular write zeroes request
+  will be faster than a regular write). Clients MUST NOT set the
+  `NBD_CMD_FLAG_FAST_ZERO` request flag unless this transmission flag
+  is set.
 
 Clients SHOULD ignore unknown flags.
 
@@ -1628,7 +1651,7 @@
   `NBD_CMD_READ`.  SHOULD be set to 1 if the client requires the
   server to send at most one content chunk in reply.  MUST NOT be set
   unless the transmission flags include `NBD_FLAG_SEND_DF`.  Use of
-  this flag MAY trigger an `EOVERFLOW` error chunk, if the request
+  this flag MAY trigger an `NBD_EOVERFLOW` error chunk, if the request
   length is too large.
 - bit 3, `NBD_CMD_FLAG_REQ_ONE`; valid during
   `NBD_CMD_BLOCK_STATUS`. If set, the client is interested in only one
@@ -1636,6 +1659,12 @@
   MUST NOT send metadata on more than one extent in the reply. Client
   implementors should note that using this flag on multiple contiguous
   requests is likely to be inefficient.
+- bit 4, `NBD_CMD_FLAG_FAST_ZERO`; valid during
+  `NBD_CMD_WRITE_ZEROES`. If set, but the server cannot perform the
+  write zeroes any faster than it would for an equivalent
+  `NBD_CMD_WRITE`, then the server MUST fail quickly with an error of
+  `NBD_ENOTSUP`. The client MUST NOT set this unless the server advertised
+  `NBD_FLAG_SEND_FAST_ZERO`.
 
 ##### Structured reply flags
 
@@ -1892,7 +1921,7 @@
     chunks or a final type of `NBD_REPLY_TYPE_NONE`).  If the area
     being read contains both data and a hole, the server MUST use
     `NBD_REPLY_TYPE_OFFSET_DATA` with the zeroes explicitly present.
-    A server MAY reject a client's request with the error `EOVERFLOW`
+    A server MAY reject a client's request with the error `NBD_EOVERFLOW`
     if the length is too large to send without fragmentation, in which
     case it MUST NOT send a content chunk; however, the server MUST
     support unfragmented reads in which the client's request length
@@ -1989,7 +2018,7 @@
     transmission flags field, however, these implementations do not
     use any command flags.  A server MAY advertise
     `NBD_FLAG_SEND_CACHE` even if the command has no effect or always
-    fails with `EINVAL`; however, if it advertised the command, the
+    fails with `NBD_EINVAL`; however, if it advertised the command, the
     server MUST reject any command flags it does not recognize.
 
 * `NBD_CMD_WRITE_ZEROES` (6)
@@ -2004,7 +2033,10 @@
     reached permanent storage, unless `NBD_CMD_FLAG_FUA` is in use.
 
     A client MUST NOT send a write zeroes request unless
-    `NBD_FLAG_SEND_WRITE_ZEROES` was set in the transmission flags field.
+    `NBD_FLAG_SEND_WRITE_ZEROES` was set in the transmission flags
+    field. Additionally, a client MUST NOT send the
+    `NBD_CMD_FLAG_FAST_ZERO` flag unless `NBD_FLAG_SEND_FAST_ZERO` was
+    set in the transmission flags field.
 
     By default, the server MAY use trimming to zero out the area, even
     if it did not advertise `NBD_FLAG_SEND_TRIM`; but it MUST ensure
@@ -2014,12 +2046,54 @@
     same area will not cause fragmentation or cause failure due to
     insufficient space.
 
+    If the server advertised `NBD_FLAG_SEND_FAST_ZERO` but
+    `NBD_CMD_FLAG_FAST_ZERO` is not set, then the server MUST NOT fail
+    with `NBD_ENOTSUP`, even if the operation is no faster than a
+    corresponding `NBD_CMD_WRITE`. Conversely, if
+    `NBD_CMD_FLAG_FAST_ZERO` is set, the server MUST fail quickly with
+    `NBD_ENOTSUP` unless the request can be serviced in less time than
+    a corresponding `NBD_CMD_WRITE`, and SHOULD NOT alter the contents
+    of the export when returning this failure. The server's
+    determination on whether to fail a fast request MAY depend on a
+    number of factors, such as whether the request was suitably
+    aligned, on whether the `NBD_CMD_FLAG_NO_HOLE` flag was present,
+    or even on whether a previous `NBD_CMD_TRIM` had been performed on
+    the region.  If the server did not advertise
+    `NBD_FLAG_SEND_FAST_ZERO`, then it SHOULD NOT fail with
+    `NBD_ENOTSUP`, regardless of the speed of servicing a request, and
+    SHOULD fail with `NBD_EINVAL` if the `NBD_CMD_FLAG_FAST_ZERO` flag
+    was set. A server MAY advertise `NBD_FLAG_SEND_FAST_ZERO` whether
+    or not it will actually succeed on a fast zero request (a fast
+    failure of `NBD_ENOTSUP` still counts as a fast response);
+    similarly, a server SHOULD fail a fast zero request with
+    `NBD_ENOTSUP` if the server cannot quickly determine in advance
+    whether proceeding with the request would be fast, even if it
+    turns out that the same request without the flag would be fast
+    after all.
+
+    One intended use of a fast zero request is optimizing the copying
+    of a sparse image source into the export: a client can request
+    fast zeroing of the entire export, and if it succeeds, follow that
+    with write requests to just the data portions before a single
+    flush of the entire image, for fewer transactions overall.  On the
+    other hand, if the fast zero request fails, the fast failure lets
+    the client know that it must manually write zeroes corresponding
+    to the holes of the source image before a final flush, for more
+    transactions but with no time lost to duplicated I/O to the data
+    portions.  Knowing this usage pattern can help decide whether a
+    server's implementation for writing zeroes counts as fast (for
+    example, a successful fast zero request may start a background
+    operation that would cause the next flush request to take longer,
+    but that is okay as long as intermediate writes before that flush
+    do not further lengthen the time spent on the overall sequence of
+    operations).
+
     If an error occurs, the server MUST set the appropriate error code
     in the error field.
 
-    The server SHOULD return `ENOSPC` if it receives a write zeroes request
+    The server SHOULD return `NBD_ENOSPC` if it receives a write zeroes request
     including one or more sectors beyond the size of the device. It SHOULD
-    return `EPERM` if it receives a write zeroes request on a read-only export.
+    return `NBD_EPERM` if it receives a write zeroes request on a read-only 
export.
 
 * `NBD_CMD_BLOCK_STATUS` (7)
 
@@ -2077,7 +2151,7 @@
 
     A client MAY initiate a hard disconnect if it detects that the
     server has sent an invalid chunk. The server SHOULD return
-    `EINVAL` if it receives a `NBD_CMD_BLOCK_STATUS` request including
+    `NBD_EINVAL` if it receives a `NBD_CMD_BLOCK_STATUS` request including
     one or more sectors beyond the size of the device.
 
 * `NBD_CMD_RESIZE` (8)
@@ -2108,33 +2182,45 @@
 
 The following error values are defined:
 
-* `EPERM` (1), Operation not permitted.
-* `EIO` (5), Input/output error.
-* `ENOMEM` (12), Cannot allocate memory.
-* `EINVAL` (22), Invalid argument.
-* `ENOSPC` (28), No space left on device.
-* `EOVERFLOW` (75), Value too large.
-* `ESHUTDOWN` (108), Server is in the process of being shut down.
+* `NBD_EPERM` (1), Operation not permitted.
+* `NBD_EIO` (5), Input/output error.
+* `NBD_ENOMEM` (12), Cannot allocate memory.
+* `NBD_EINVAL` (22), Invalid argument.
+* `NBD_ENOSPC` (28), No space left on device.
+* `NBD_EOVERFLOW` (75), Value too large.
+* `NBD_ENOTSUP` (95), Operation not supported.
+* `NBD_ESHUTDOWN` (108), Server is in the process of being shut down.
 
-The server SHOULD return `ENOSPC` if it receives a write request
+The server SHOULD return `NBD_ENOSPC` if it receives a write request
 including one or more sectors beyond the size of the device.  It also
-SHOULD map the `EDQUOT` and `EFBIG` errors to `ENOSPC`.  It SHOULD
-return `EINVAL` if it receives a read or trim request including one or
+SHOULD map the `EDQUOT` and `EFBIG` errors to `NBD_ENOSPC`.  It SHOULD
+return `NBD_EINVAL` if it receives a read or trim request including one or
 more sectors beyond the size of the device, or if a read or write
 request is not aligned to advertised minimum block sizes. Finally, it
-SHOULD return `EPERM` if it receives a write or trim request on a
+SHOULD return `NBD_EPERM` if it receives a write or trim request on a
 read-only export.
 
-The server SHOULD return `EINVAL` if it receives an unknown command.
+The server SHOULD NOT return `NBD_EOVERFLOW` except as documented in
+response to `NBD_CMD_READ` when `NBD_CMD_FLAG_DF` is supported.
 
-The server SHOULD return `EINVAL` if it receives an unknown command flag. It
-also SHOULD return `EINVAL` if it receives a request with a flag not explicitly
-documented as applicable to the given request.
+The server SHOULD NOT return `NBD_ENOTSUP` except as documented in
+response to `NBD_CMD_WRITE_ZEROES` when `NBD_CMD_FLAG_FAST_ZERO` is
+supported.
+
+The server SHOULD return `NBD_EINVAL` if it receives an unknown command.
+
+The server SHOULD return `NBD_EINVAL` if it receives an unknown
+command flag. It also SHOULD return `NBD_EINVAL` if it receives a
+request with a flag not explicitly documented as applicable to the
+given request.
 
 Which error to return in any other case is not specified by the NBD
 protocol.
 
-The server SHOULD NOT return `ENOMEM` if at all possible.
+The server SHOULD NOT return `NBD_ENOMEM` if at all possible.
+
+The client SHOULD treat an unexpected error value as if it had been
+`NBD_EINVAL`, rather than disconnecting from the server.
 
 ## Experimental extensions
 
@@ -2169,6 +2255,83 @@
 when those extensions are promoted to the normative version
 of the document in the master branch.
 
+## Compatibility and interoperability
+
+Originally, the NBD protocol was a fairly simple protocol with few
+options. While the basic protocol is still reasonably simple, a growing
+number of extensions has been implemented that may make the protocol
+description seem overwhelming at first.
+
+In an effort to not overwhelm first-time implementors with various
+options and features that may or may not be important for their use
+case, while at the same time desiring maximum interoperability, this
+section tries to clarify what is optional and what is expected to be
+available in all implementations.
+
+All protocol options and messages not explicitly mentioned below should
+be considered optional features that MAY be negotiated between client
+and server, but are not required to be available.
+
+### Baseline
+
+The following MUST be implemented by all implementations, and should be
+considered a baseline:
+
+- NOTLS mode
+- The fixed newstyle handshake
+- During the handshake:
+
+    - the `NBD_OPT_INFO` and `NBD_OPT_GO` messages, with the
+      `NBD_INFO_EXPORT` response.
+    - Servers that receive messages which they do not implement MUST
+      reply to them with `NBD_OPT_UNSUP`, and MUST NOT fail to parse
+      the next message received.
+    - the `NBD_OPT_ABORT` message, and its response.
+    - the `NBD_OPT_LIST` message and its response.
+
+- During the transmission phase:
+
+    - Simple replies
+    - the `NBD_CMD_READ` message (and its response)
+    - the `NBD_CMD_WRITE` message (and its response), unless the
+      implementation is a client that does not wish to write
+    - the `NBD_CMD_DISC` message (and its resulting effects, although
+      no response is involved)
+
+Clients that wish to use more messages MUST negotiate them during the
+handshake phase, first.
+
+### Maximum interoperability
+
+Clients and servers that desire maximum interoperability SHOULD
+implement the following features:
+
+- TLS-encrypted communication, which may be required by some
+  implementations or configurations;
+- Servers that implement block constraints through `NBD_INFO_BLOCK_SIZE`
+  and desire maximum interoperability SHOULD NOT require them.
+  Similarly, clients that desire maximum interoperability SHOULD
+  implement querying for block size constraints. Since some clients
+  default to a block size of 512 bytes, implementations desiring maximum
+  interoperability MAY default to that size.
+- Clients or servers that desire interoperability with older
+  implementations SHOULD implement the `NBD_OPT_EXPORT_NAME` message in
+  addition to `NBD_OPT_INFO` and `NBD_OPT_GO`.
+- For data safety, implementing `NBD_CMD_FLUSH` and the
+  `NBD_CMD_FLAG_FUA` flag to `NBD_CMD_WRITE` is strongly recommended.
+  Clients that do not implement querying for block size constraints
+  SHOULD abide by the rules laid out in the section "Block size
+  constraints", above.
+
+### Future considerations
+
+The following may be moved to the "Maximum interoperability" or
+"Baseline" sections at some point in the future, but some significant
+implementations are not yet ready to support them:
+
+- Structured replies; the Linux kernel currently does not yet implement
+  them.
+
 ## About this file
 
 This file tries to document the NBD protocol as it is currently
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/doc/uri.md new/nbd-3.20/doc/uri.md
--- old/nbd-3.19/doc/uri.md     1970-01-01 01:00:00.000000000 +0100
+++ new/nbd-3.20/doc/uri.md     2019-09-15 13:35:52.000000000 +0200
@@ -0,0 +1,171 @@
+# The NBD Uniform Resource Indicator (URI) format
+
+## Introduction
+
+This document describes the standard URI format that clients may use
+to refer to an export located on an NBD server.
+
+## Convention
+
+"NBD" stands for Network Block Device and refers to the protocol
+described in the adjacent protocol document also available online at
+<https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#the-nbd-protocol>
+
+"URI" stands for Uniform Resource Indicator and refers to the standard
+introduced in [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt) and
+subsequent IETF standards.
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
+"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",
+"MAY", and "OPTIONAL" in this document are to be interpreted as
+described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
+The same words in lower case carry their natural meaning.
+
+## Related standards
+
+All NBD URIs MUST also be valid URIs as described in
+[RFC 3986](https://www.ietf.org/rfc/rfc3986.txt) and any subsequent
+IETF standards describing URIs.  This means that any parsing, quoting
+or encoding issues that may arise when making or parsing an NBD URI
+must be answered by consulting IETF standards.
+
+This standard defers any question about how the NBD protocol works to
+the NBD protocol document available online at
+<https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#the-nbd-protocol>
+
+## NBD URI components
+
+An NBD URI consists of the following components:
+
+     +------- Scheme (required)
+     |
+     |            +------- Authority (optional)
+     |            |
+     |            |           +------- Export name (optional)
+     |            |           |
+     v            v           v
+    nbd://example.com:10809/export
+    
+    nbd+unix:///export?socket=nbd.sock
+                           ^
+                           |
+                           +---- Query parameters
+
+## NBD URI scheme
+
+One of the following scheme names SHOULD be used to indicate an NBD URI:
+
+* `nbd`: NBD over an unencrypted or opportunistically TLS encrypted
+  TCP/IP connection.
+
+* `nbds`: NBD over a TLS encrypted TCP/IP connection.  If encryption
+  cannot be negotiated then the connection MUST fail.
+
+* `nbd+unix`: NBD over a Unix domain socket.  The query parameters
+  MUST include a parameter called `socket` which refers to the name of
+  the Unix domain socket.
+
+* `nbds+unix`: NBD over a TLS encrypted Unix domain socket.  If
+  encryption cannot be negotiated then the connection MUST fail.  The
+  query parameters MUST include a parameter called `socket` which
+  refers to the name of the Unix domain socket.
+
+Other URI scheme names MAY be used but not all NBD clients will
+understand them or even recognize that they refer to NBD.
+
+## NBD URI authority
+
+The authority field SHOULD be used for TCP/IP connections and SHOULD
+NOT be used for Unix domain socket connections.
+
+The authority field MAY contain the `userinfo`, `host` and/or `port`
+fields as defined in [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt)
+section 3.2.
+
+The `host` field may be a host name or IP address.  Literal IPv6
+addresses MUST be formatted in the way specified by
+[RFC 2732](https://www.ietf.org/rfc/rfc2732.txt).
+
+If the `port` field is not present then it MUST default to the NBD
+port number assigned by IANA (10809).
+
+The `userinfo` field is used to supply a username for certain less
+common sorts of TLS authentication.  If the `userinfo` field is not
+present but is needed by the client for TLS authentication then it
+SHOULD default to a local operating system credential if one is
+available.
+
+It is up to the NBD client what should happen if the authority field
+is not present for TCP/IP connections, or present for Unix domain
+socket connections.  Options might include failing with an error,
+ignoring it, or using defaults.
+
+## NBD URI export name
+
+If the version of the NBD protocol in use needs an export name, then
+the path part of the URI except for the leading `/` character MUST be
+passed to the server as the export name.
+
+For example:
+
+    NBD URI                          Export name
+    ----------------------------------------------------
+    nbd://example.com/disk           disk
+    nbd+unix:///disk?socket=sock     disk
+    nbd://example.com/               (empty string)
+    nbd://example.com                (empty string)
+    nbd://example.com//disk          /disk
+    nbd://example.com/hello%20world  hello world
+
+Note that export names are not usually paths, they are free text
+strings.  In particular they do not usually start with a `/`
+character, they may be an empty string, and they may contain any
+Unicode character except NUL.
+
+## NBD URI socket parameter
+
+If the scheme name indicates a Unix domain socket then the query
+parameters MUST include a `socket` key, referring to the Unix domain
+socket which on Unix-like systems is usually a special file on the
+local disk.
+
+On platforms which support Unix domain sockets in the abstract
+namespace, and if the client supports this, the `socket` parameter MAY
+begin with an ASCII NUL character.  When the URI is properly encoded
+it will look like this:
+
+    nbd+unix:///?socket=%00/abstract
+
+## NBD URI query parameters related to TLS
+
+If TLS encryption is to be negotiated then the following query
+parameters MAY be present:
+
+* `tls-type`: Possible values include `anon`, `x509` or `psk`.  This
+  specifies the desired TLS authentication method.
+
+* `tls-hostname`: The optional TLS hostname to use for certificate
+  verification.  This can be used when connecting over a Unix domain
+  socket since there is no hostname available in the URI authority
+  field; or when DNS does not properly resolve the server's hostname.
+
+* `tls-verify-peer`: This optional parameter may be `0` or `1` to
+  control whether the client verifies the server's identity.  By
+  default clients SHOULD verify the server's identity if TLS is
+  negotiated and if a suitable Certificate Authority is available.
+
+## Other NBD URI query parameters
+
+Clients SHOULD prefix experimental query parameters using `x-`.  This
+SHOULD NOT be used for query parameters which are expected to be
+widely used.
+
+Any other query parameters which the client does not understand SHOULD
+be diagnosed by the parser.
+
+## Clients which do not support TLS
+
+Wherever this document refers to encryption, authentication and TLS,
+clients which do not support TLS SHOULD give an error when
+encountering an NBD URI that requires TLS (such as one with a scheme
+name `nbds` or `nbds+unix`).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/man/nbd-server.5.in.sgml new/nbd-3.20/man/nbd-server.5.in.sgml
--- old/nbd-3.19/man/nbd-server.5.in.sgml       2019-01-30 16:31:20.000000000 
+0100
+++ new/nbd-3.20/man/nbd-server.5.in.sgml       2019-05-22 15:14:30.000000000 
+0200
@@ -490,6 +490,13 @@
          <para>When specified on the command line, this should be the
            second argument.
          </para>
+         <para><emphasis>Note:</emphasis> this is <emphasis>not</emphasis>
+         the "exportname" as defined in the protocol document, and
+         which is the name that <command>nbd-client</command> needs to
+         pass to select the correct export; the section name is used
+         for that. The name of the file to be exported is called the
+         exportname in the configuration file for historical reasons,
+         and cannot easily be changed.</para>
        </listitem>
       </varlistentry>
       <varlistentry>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/man/nbd-server.5.sh.in new/nbd-3.20/man/nbd-server.5.sh.in
--- old/nbd-3.19/man/nbd-server.5.sh.in 2019-01-30 16:31:23.000000000 +0100
+++ new/nbd-3.20/man/nbd-server.5.sh.in 2019-05-25 20:44:16.000000000 +0200
@@ -327,6 +327,14 @@
 
 When specified on the command line, this should be the
 second argument.
+
+\fBNote:\fR this is \fBnot\fR
+the "exportname" as defined in the protocol document, and
+which is the name that \fBnbd-client\fR needs to
+pass to select the correct export; the section name is used
+for that. The name of the file to be exported is called the
+exportname in the configuration file for historical reasons,
+and cannot easily be changed.
 .TP
 \fBfilesize\fR
 Optional; integer; default autodetected.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/nbd-client.c new/nbd-3.20/nbd-client.c
--- old/nbd-3.19/nbd-client.c   2019-01-30 16:24:10.000000000 +0100
+++ new/nbd-3.20/nbd-client.c   2019-09-15 13:35:52.000000000 +0200
@@ -469,7 +469,7 @@
                err("E: server does not support NBD_OPT_GO and dropped 
connection after sending NBD_OPT_EXPORT_NAME. Try -g.");
        }
        parse_sizes(b, rsize64, flags);
-       if(!global_flags & NBD_FLAG_NO_ZEROES) {
+       if(!(global_flags & NBD_FLAG_NO_ZEROES)) {
                char buf[125];
                readit(sock, buf, 124);
        }
@@ -933,7 +933,7 @@
 }
 
 #if HAVE_NETLINK
-static const char *short_opts = "-A:b:c:C:d:H:hK:LlnN:pSst:uVx";
+static const char *short_opts = "-A:b:c:C:d:gH:hK:LlnN:pSst:uVx";
 #else
 static const char *short_opts = "-A:b:c:C:d:gH:hK:lnN:pSst:uVx";
 #endif
@@ -1052,6 +1052,10 @@
                case 'b':
                      blocksize:
                        blocksize=(int)strtol(optarg, NULL, 0);
+                       if(blocksize == 0 || (blocksize % 512) != 0) {
+                               fprintf(stderr, "E: blocksize is not a multiple 
of 512! This is not allowed\n");
+                               exit(EXIT_FAILURE);
+                       }
                        break;
                case 'c':
                        return check_conn(optarg, 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/nbd-server.c new/nbd-3.20/nbd-server.c
--- old/nbd-3.19/nbd-server.c   2018-11-27 17:29:21.000000000 +0100
+++ new/nbd-3.20/nbd-server.c   2019-09-15 13:35:52.000000000 +0200
@@ -95,6 +95,9 @@
 #if HAVE_FALLOC_PH
 #include <linux/falloc.h>
 #endif
+#if HAVE_BLKDISCARD
+#include <linux/fs.h>
+#endif
 #include <arpa/inet.h>
 #include <strings.h>
 #include <dirent.h>
@@ -444,6 +447,7 @@
        if(client->server->flags & F_COPYONWRITE) {
                unlink(client->difffilename);
        }
+       serve_dec_ref(client->server);
 }
 
 static inline void socket_closed_transmission(CLIENT* client) {
@@ -560,7 +564,7 @@
        if(argc==1) {
                return NULL;
        }
-       serve=g_new0(SERVER, 1);
+       serve=serve_inc_ref((SERVER*)g_new0(SERVER, 1));
        serve->authname = g_strdup(default_authname);
        serve->virtstyle=VIRT_IPLIT;
        while((c=getopt_long(argc, argv, "-C:cwdl:mo:rp:M:V", long_options, 
&i))>=0) {
@@ -661,8 +665,7 @@
        /* What's left: the port to export, the name of the to be exported
         * file, and, optionally, the size of the file, in that order. */
        if(nonspecial<2) {
-               g_free(serve);
-               serve=NULL;
+               serve=serve_dec_ref(serve);
        } else {
                serve->servename = "";
        }
@@ -711,8 +714,9 @@
                switch(NBD_D_TYPE) {
                        case DT_UNKNOWN:
                                /* Filesystem doesn't return type of
-                                * file through readdir. Run stat() on
-                                * the file instead */
+                                * file through readdir, or struct dirent
+                                * doesn't have d_type. Run stat() on the file
+                                * instead */
                                if(stat(fname, &stbuf)) {
                                        perror("stat");
                                        goto err_out;
@@ -731,7 +735,7 @@
                                        goto err_out;
                                }
                                if(!retval)
-                                       retval = g_array_new(FALSE, TRUE, 
sizeof(SERVER));
+                                       retval = g_array_new(FALSE, TRUE, 
sizeof(SERVER*));
                                retval = g_array_append_vals(retval, tmp->data, 
tmp->len);
                                g_array_free(tmp, TRUE);
                        default:
@@ -852,7 +856,10 @@
         }
 
        cfile = g_key_file_new();
-       retval = g_array_new(FALSE, TRUE, sizeof(SERVER));
+       retval = g_array_new(FALSE, TRUE, sizeof(SERVER*));
+       if(expect_generic) {
+               g_array_set_clear_func(retval, (GDestroyNotify)serve_dec_ref);
+       }
        if(!g_key_file_load_from_file(cfile, f, G_KEY_FILE_KEEP_COMMENTS |
                        G_KEY_FILE_KEEP_TRANSLATIONS, &err)) {
                g_set_error(e, NBDS_ERR, NBDS_ERR_CFILE_NOTFOUND, "Could not 
open config file %s: %s",
@@ -1000,7 +1007,8 @@
                if(i>0 || !expect_generic) {
                        s.servename = groups[i];
 
-                       g_array_append_val(retval, s);
+                       SERVER *srv = serve_inc_ref(g_memdup(&s, 
sizeof(SERVER)));
+                       g_array_append_val(retval, srv);
                }
 #ifndef WITH_SDP
                if(s.flags & F_SDP) {
@@ -1555,19 +1563,38 @@
 }
 
 void punch_hole(int fd, off_t off, off_t len) {
-       DEBUG("punching hole in fd=%d, starting from %llu, length %llu\n", fd, 
(unsigned long long)off, (unsigned long long)len);
+       DEBUG("Request to punch a hole in fd=%d, starting from %llu, length 
%llu\n", fd, (unsigned long long)off, (unsigned long long)len);
+       errno = 0;
+// fallocate -- files, Linux
 #if HAVE_FALLOC_PH
-       fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, off, len);
-#elif HAVE_FSCTL_SET_ZERO_DATA
+       do {
+               if(fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 
off, len) == 0)
+                       return;
+       } while(errno == EINTR);
+#endif
+// ioctl(BLKDISCARD) -- block devices, Linux
+#if HAVE_BLKDISCARD
+       uint64_t range[2] = {off, len};
+       do {
+               if(ioctl(fd, BLKDISCARD, range) == 0)
+                       return;
+       } while(errno == EINTR);
+#endif
+// Windows
+#if HAVE_FSCTL_SET_ZERO_DATA
        FILE_ZERO_DATA_INFORMATION zerodata;
        zerodata.FileOffset.QuadPart = off;
        zerodata.BeyondFinalZero.QuadPart = off + len;
        HANDLE w32handle = (HANDLE)_get_osfhandle(fd);
        DWORD bytesret;
        DeviceIoControl(w32handle, FSCTL_SET_ZERO_DATA, &zerodata, 
sizeof(zerodata), NULL, 0, &bytesret, NULL);
-#else
-       DEBUG("punching holes not supported on this platform\n");
+       return;
 #endif
+       if(errno) {
+               DEBUG("punching holes failed: %s", strerror(errno));
+       } else {
+               DEBUG("punching holes not supported on this platform\n");
+       }
 }
 
 static void send_reply(CLIENT* client, uint32_t opt, uint32_t reply_type, 
ssize_t datasize, void* data) {
@@ -1702,7 +1729,9 @@
                        break;
        }
 
-       freeaddrinfo(ai);
+       if(ai) {
+               freeaddrinfo(ai);
+       }
         msg(LOG_INFO, "connect from %s, assigned file is %s",
             peername, client->exportname);
        client->clientname=g_strdup(peername);
@@ -1989,7 +2018,7 @@
        char acl;
        uint32_t len;
 
-       client->server = server;
+       client->server = serve_inc_ref(server);
        client->exportsize = OFFT_MAX;
        client->transactionlogfd = -1;
        if(pthread_mutex_init(&(client->lock), NULL)) {
@@ -2087,7 +2116,7 @@
                name = strdup("");
        }
        for(i=0; i<servers->len; i++) {
-               SERVER* serve = &(g_array_index(servers, SERVER, i));
+               SERVER* serve = (g_array_index(servers, SERVER*, i));
                // hide exports that are TLS-only if we haven't negotiated TLS
                // yet
                if ((serve->flags & F_FORCEDTLS) && !client->tls_session) {
@@ -2124,7 +2153,7 @@
                return;
        }
        for(i=0; i<servers->len; i++) {
-               SERVER* serve = &(g_array_index(servers, SERVER, i));
+               SERVER* serve = (g_array_index(servers, SERVER*, i));
                // Hide TLS-only exports if we haven't negotiated TLS yet
                if(!client->tls_session && (serve->flags & F_FORCEDTLS)) {
                        continue;
@@ -2272,7 +2301,7 @@
                name = strdup("");
        }
        for(i=0; i<servers->len; i++) {
-               SERVER *serve = &(g_array_index(servers, SERVER, i));
+               SERVER *serve = (g_array_index(servers, SERVER*, i));
                if (!strcmp(serve->servename, name)) {
                        if ((serve->flags & F_FORCEDTLS) && 
!client->tls_session) {
                                reptype = NBD_REP_ERR_TLS_REQD;
@@ -2914,12 +2943,6 @@
                 /* Now that we are in the child process after a
                  * succesful negotiation, we do not need the list of
                  * servers anymore, get rid of it.*/
-                /* FALSE does not free the
-                   actual data. This is required,
-                   because the client has a
-                   direct reference into that
-                   data, and otherwise we get a
-                   segfault... */
                 g_array_free(servers, FALSE);
         }
 
@@ -2955,10 +2978,10 @@
                }
        }
        buf = g_malloc0(len + 1);
-       buf[len] = 0;
        readit(socket, buf, len);
+       buf[len] = 0;
        for(i=0; i<servers->len; i++) {
-               SERVER* srv = &g_array_index(servers, SERVER, i);
+               SERVER* srv = g_array_index(servers, SERVER*, i);
                if(strcmp(srv->servename, buf) == 0) {
                        if(srv->max_connections == 0 || srv->max_connections > 
srv->numclients) {
                                writeit(socket, "Y", 1);
@@ -2989,9 +3012,9 @@
         int i;
 
         for (i = 0; i < servers->len; ++i) {
-                const SERVER server = g_array_index(servers, SERVER, i);
+                const SERVER* server = g_array_index(servers, SERVER*, i);
 
-                if (strcmp(servename, server.servename) == 0)
+                if (strcmp(servename, server->servename) == 0)
                         return i;
         }
 
@@ -3005,26 +3028,26 @@
  * is unique among all other servers.
  *
  * @param servers an array of servers
+ * @param genconf a pointer to generic configuration
  * @return the number of new servers appended to the array, or -1 in
  *         case of an error
  **/
-static int append_new_servers(GArray *const servers, GError **const gerror) {
+static int append_new_servers(GArray *const servers, struct generic_conf 
*genconf, GError **const gerror) {
         int i;
         GArray *new_servers;
         const int old_len = servers->len;
         int retval = -1;
-        struct generic_conf genconf;
 
-        new_servers = parse_cfile(config_file_pos, &genconf, true, gerror);
-       g_thread_pool_set_max_threads(tpool, genconf.threads, NULL);
+        new_servers = parse_cfile(config_file_pos, genconf, true, gerror);
+        g_thread_pool_set_max_threads(tpool, genconf->threads, NULL);
         if (!new_servers)
                 goto out;
 
         for (i = 0; i < new_servers->len; ++i) {
-                SERVER new_server = g_array_index(new_servers, SERVER, i);
+                SERVER *new_server = g_array_index(new_servers, SERVER*, i);
 
-                if (new_server.servename
-                    && -1 == get_index_by_servename(new_server.servename,
+                if (new_server->servename
+                    && -1 == get_index_by_servename(new_server->servename,
                                                     servers)) {
                        g_array_append_val(servers, new_server);
                 }
@@ -3127,17 +3150,17 @@
                         is_sighup_caught = 0; /* Reset to allow catching
                                                * it again. */
 
-                        n = append_new_servers(servers, &gerror);
+                        n = append_new_servers(servers, genconf, &gerror);
                         if (n == -1)
                                 msg(LOG_ERR, "failed to append new servers: 
%s",
                                     gerror->message);
 
                         for (i = servers->len - n; i < servers->len; ++i) {
-                                const SERVER server = g_array_index(servers,
-                                                                    SERVER, i);
+                                const SERVER *server = g_array_index(servers,
+                                                                    SERVER*, 
i);
 
                                 msg(LOG_INFO, "reconfigured new server: %s",
-                                    server.servename);
+                                    server->servename);
                         }
                 }
 
@@ -3545,7 +3568,7 @@
         glob_flags   |= genconf.flags;
 
        if(serve) {
-               g_array_append_val(servers, *serve);
+               g_array_append_val(servers, serve);
        }
     
        if(!servers || !servers->len) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/nbdsrv.c new/nbd-3.20/nbdsrv.c
--- old/nbd-3.19/nbdsrv.c       2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/nbdsrv.c       2019-05-25 22:38:33.000000000 +0200
@@ -11,19 +11,22 @@
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <pthread.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <treefiles.h>
 #include "backend.h"
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
 #ifdef HAVE_SYS_MOUNT_H
 #include <sys/mount.h>
 #endif
 
 #define LINELEN 256      /**< Size of static buffer used to read the
                               authorization file (yuck) */
-
 #include <cliserv.h>
 
 bool address_matches(const char* mask, const struct sockaddr* addr, GError** 
err) {
@@ -278,3 +281,22 @@
        DEBUG("Performed TRIM request from %llu to %llu", (unsigned long long) 
req->from, (unsigned long long) req->len);
        return 0;
 }
+
+pthread_mutex_t cntmutex = PTHREAD_MUTEX_INITIALIZER;
+
+SERVER* serve_inc_ref(SERVER *s) {
+       pthread_mutex_lock(&cntmutex);
+       s->refcnt++;
+       pthread_mutex_unlock(&cntmutex);
+       return s;
+}
+
+SERVER* serve_dec_ref(SERVER *s) {
+       pthread_mutex_lock(&cntmutex);
+       if(--(s->refcnt) == 0) {
+               g_free(s);
+               s = NULL;
+       }
+       pthread_mutex_unlock(&cntmutex);
+       return s;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/nbdsrv.h new/nbd-3.20/nbdsrv.h
--- old/nbd-3.19/nbdsrv.h       2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/nbdsrv.h       2019-04-12 22:28:33.000000000 +0200
@@ -46,6 +46,7 @@
        int numclients;      /**< number of clients connected to this export */
        gchar* transactionlog;/**< filename for transaction log */
        gchar* cowdir;       /**< directory for copy-on-write diff files. */
+       int refcnt;          /**< reference counter */
 } SERVER;
 
 /**
@@ -205,6 +206,20 @@
 uint64_t size_autodetect(int fhandle);
 
 /**
+ * increase the ref counter for a SERVER
+ *
+ * @param s the server to increase
+ **/
+SERVER* serve_inc_ref(SERVER *s);
+
+/**
+ * decrement the reference counter or a SERVER
+ *
+ * @param s the server to decrement
+ **/
+SERVER* serve_dec_ref(SERVER *s);
+
+/**
  * Punch a hole in the backend file (if supported by the current system).
  *
  * @param req the request for which this is being processed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/tests/code/Makefile.am new/nbd-3.20/tests/code/Makefile.am
--- old/nbd-3.19/tests/code/Makefile.am 2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/tests/code/Makefile.am 2019-04-12 17:18:59.000000000 +0200
@@ -6,16 +6,16 @@
 AM_CPPFLAGS = -I$(top_srcdir)
 
 clientacl_SOURCES = clientacl.c punchdummy.c
-clientacl_LDADD = $(top_builddir)/libnbdsrv.la @GLIB_LIBS@
+clientacl_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la 
@GLIB_LIBS@
 
 dup_SOURCES = dup.c punchdummy.c
-dup_LDADD = $(top_builddir)/libnbdsrv.la @GLIB_LIBS@
+dup_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la 
@GLIB_LIBS@
 
 mask_SOURCES = mask.c punchdummy.c
-mask_LDADD = $(top_builddir)/libnbdsrv.la @GLIB_LIBS@
+mask_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la 
@GLIB_LIBS@
 
 size_SOURCES = size.c punchdummy.c
-size_LDADD = $(top_builddir)/libnbdsrv.la @GLIB_LIBS@
+size_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la 
@GLIB_LIBS@
 
 trim_SOURCES = trim.c
-trim_LDADD = $(top_builddir)/libnbdsrv.la @GLIB_LIBS@
+trim_LDADD = $(top_builddir)/libnbdsrv.la $(top_builddir)/libcliserv.la 
@GLIB_LIBS@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/tests/code/size.c new/nbd-3.20/tests/code/size.c
--- old/nbd-3.19/tests/code/size.c      2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/tests/code/size.c      2019-09-15 13:35:52.000000000 +0200
@@ -8,7 +8,8 @@
        int fd = mkstemp(filename);
        unlink(filename);
 
-       lseek(fd, 1023, SEEK_SET);
+       count_assert(fd >= 0);
+       count_assert(lseek(fd, 1023, SEEK_SET) == 1023);
        count_assert(write(fd, filename, 1) == 1);
 
        count_assert(size_autodetect(fd) == 1024);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/tests/run/nbd-tester-client.c 
new/nbd-3.20/tests/run/nbd-tester-client.c
--- old/nbd-3.19/tests/run/nbd-tester-client.c  2018-11-23 12:27:50.000000000 
+0100
+++ new/nbd-3.20/tests/run/nbd-tester-client.c  2019-09-15 13:35:52.000000000 
+0200
@@ -373,6 +373,7 @@
                goto end;
        READ_ALL_ERRCHK(sock, buf, strlen(INIT_PASSWD), err,
                        "Could not read INIT_PASSWD: %s", strerror(errno));
+       buf[strlen(INIT_PASSWD)] = 0;
        if (strlen(buf) == 0) {
                snprintf(errstr, errstr_len, "Server closed connection");
                goto err;
@@ -538,7 +539,7 @@
 #endif
        if(testflags & TEST_EXPECT_ERROR) {
                struct sigaction act;
-               memset(&act, '0', sizeof act);
+               memset(&act, 0, sizeof act);
                act.sa_handler = SIG_IGN;
                sigaction(SIGPIPE, &act, NULL);
        }
@@ -621,6 +622,7 @@
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = *((int *)host->h_addr);
+       memset(&addr.sin_zero, 0, sizeof(addr.sin_zero));
        if ((connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)) {
                strncpy(errstr, strerror(errno), errstr_len);
                goto err_open;
@@ -688,6 +690,7 @@
                                 strerror(errno));
                        return -1;
                }
+               /* falls through */
        case CONNECTION_CLOSE_FAST:
                if (close(sock) < 0) {
                        snprintf(errstr, errstr_len,
@@ -1780,9 +1783,10 @@
 #ifndef ISSERVER
                        err_nonfatal("inetd mode not supported without syslog 
support");
                        return 77;
-#endif
+#else
                        p = -1;
                        break;
+#endif
                case 'i':
                        test = integrity_test;
                        break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/nbd-3.19/tests/run/simple_test new/nbd-3.20/tests/run/simple_test
--- old/nbd-3.19/tests/run/simple_test  2018-11-23 12:27:50.000000000 +0100
+++ new/nbd-3.20/tests/run/simple_test  2019-04-12 12:55:36.000000000 +0200
@@ -20,6 +20,7 @@
 certdir=$($REALPATH ${mydir}/certs)
 cleanup="$2"
 PID=""
+DELAY=${DELAY:-1}
 
 set -e
 
@@ -67,7 +68,7 @@
                # -p only works if nbd-server wasn't compiled with -DNOFORK or
                # -DNODAEMON, which I sometimes do for testing and debugging.
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -o -N export 127.0.0.1
                retval=$?
        ;;
@@ -80,7 +81,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export 127.0.0.1
                retval=$?
        ;;
@@ -100,7 +101,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 localhost
                retval=$?
                if [ $retval -ne 0 ]
@@ -129,7 +130,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 localhost
                retval=$?
        ;;
@@ -142,7 +143,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -w localhost
                retval=$?
        ;;
@@ -157,7 +158,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -w localhost
                retval=$?
        ;;
@@ -173,7 +174,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -w -F localhost
                retval=$?
        ;;
@@ -189,7 +190,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -w -f localhost
                retval=$?
        ;;
@@ -206,7 +207,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 localhost
                retval=$?
        ;;
@@ -224,7 +225,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -i -t ${mydir}/integrity-test.tr 
localhost
                retval=$?
        ;;
@@ -242,7 +243,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -i -t 
${mydir}/integrityhuge-test.tr localhost
                retval=$?
        ;;
@@ -265,7 +266,7 @@
 EOF
                        ../../nbd-server -C ${conffile} -p ${pidfile} &
                        PID=$!
-                       sleep 1
+                       sleep $DELAY
                        ../../nbd-client -l localhost
                        ./nbd-tester-client -N export1 localhost
                        retval=$?
@@ -281,7 +282,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -w -F localhost
                retval=$?
                ;;
@@ -295,7 +296,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -u ${tmpdir}/unix.sock
                retval=$?
                ;;
@@ -318,7 +319,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -h -N export1 localhost
                retval=$?
        ;;
@@ -339,7 +340,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -i -t 
"${mydir}/integrity-test.tr" -C "${certdir}/client-cert.pem" -K 
"${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" localhost
                retval=$?
        ;;
@@ -361,7 +362,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -i -t 
"${mydir}/integrityhuge-test.tr" -C "${certdir}/client-cert.pem" -K 
"${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" -H localhost 127.0.0.1
                retval=$?
        ;;
@@ -381,7 +382,7 @@
 EOF
                ../../nbd-server -C ${conffile} -p ${pidfile} &
                PID=$!
-               sleep 1
+               sleep $DELAY
                ./nbd-tester-client -N export1 -t "${mydir}/integrity-test.tr" 
-C "${certdir}/selfsigned-cert.pem" -K "${certdir}/selfsigned-key.pem" -F 
localhost
                retval=$?
        ;;


Reply via email to