Rebase to libnbd 1.23.7

resolves: RHEL-111243
This commit is contained in:
Richard W.M. Jones 2025-08-29 15:08:58 +01:00
parent 9a8baa8dc3
commit 1809c4bb0d
22 changed files with 366 additions and 2508 deletions

View File

@ -0,0 +1,114 @@
From 1f2ba448ffd703d3e19016fdc52bc181fb902346 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 24 Aug 2025 13:58:33 +0100
Subject: [PATCH] lib/uri.c: Replace nbd-user with tls-username
Commit f9df1ba621 added a new nbd-user parameter which let you
override the TLS username. It was misnamed, and should have been
called tls-username, both to reflect its actual use and to fit in with
the other tls-* parameters, so let's rename it.
Renaming it also allows simplifying the loop which checks for other
query parameters.
Updates: commit f9df1ba621cffc3ef74fdb27650c9258b0abd3fc
---
generator/API.ml | 16 ++++++++--------
lib/uri.c | 25 ++++++++++++-------------
2 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/generator/API.ml b/generator/API.ml
index ab135004..c434e3e6 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -2075,14 +2075,6 @@ For SSH transport, this specifies the port used to connect to
the NBD server, but the port in the authority field is used for
the SSH connection.
-=item B<nbd-user=>C<USER>
-
-Override the username from the authority part of the URI.
-
-For SSH transport, this specifies the user for connecting to
-the NBD server, but the user in the authority field is used
-for the SSH connection.
-
=item B<socket=>F<SOCKET>
Specifies the Unix domain socket to connect on.
@@ -2103,6 +2095,14 @@ this is not allowed by default - see next section.
Set the TLS hostname. See L<nbd_set_tls_hostname(3)>.
+=item B<tls-username=>C<USER>
+
+Override the username from the authority part of the URI.
+
+For SSH transport, this specifies the TLS username for connecting to
+the NBD server, but the user in the authority field is used
+for the SSH connection.
+
=item B<tls-verify-peer=false>
Do not verify the server certificate. See L<nbd_set_tls_verify_peer(3)>.
diff --git a/lib/uri.c b/lib/uri.c
index e110bc34..45ba531c 100644
--- a/lib/uri.c
+++ b/lib/uri.c
@@ -350,7 +350,7 @@ nbd_unlocked_aio_connect_uri (struct nbd_handle *h, const char *raw_uri)
uri_query_list queries = empty_vector;
int i, r;
int ret = -1;
- const char *nbd_user = NULL, *nbd_port = NULL;
+ const char *nbd_port = NULL;
const char *tls_username = NULL;
const char *unixsocket = NULL;
@@ -489,9 +489,12 @@ nbd_unlocked_aio_connect_uri (struct nbd_handle *h, const char *raw_uri)
if (tls && nbd_unlocked_set_tls (h, LIBNBD_TLS_REQUIRE) == -1)
goto cleanup;
- /* Look for some tls-* parameters. */
+ /* Look for some other query parameters. */
for (i = 0; i < queries.len; i++) {
- if (strcasecmp (queries.ptr[i].name, "tls-certificates") == 0) {
+ if (strcasecmp (queries.ptr[i].name, "nbd-port") == 0) {
+ nbd_port = queries.ptr[i].value;
+ }
+ else if (strcasecmp (queries.ptr[i].name, "tls-certificates") == 0) {
if (! h->uri_allow_local_file) {
set_error (EPERM,
"local file access (tls-certificates) is not allowed, "
@@ -515,6 +518,9 @@ nbd_unlocked_aio_connect_uri (struct nbd_handle *h, const char *raw_uri)
if (nbd_unlocked_set_tls_hostname (h, queries.ptr[i].value) == -1)
goto cleanup;
}
+ else if (strcasecmp (queries.ptr[i].name, "tls-username") == 0) {
+ tls_username = queries.ptr[i].value; /* set below */
+ }
else if (strcasecmp (queries.ptr[i].name, "tls-verify-peer") == 0) {
int v = parse_bool ("tls-verify-peer", queries.ptr[i].value);
if (v == -1)
@@ -524,16 +530,9 @@ nbd_unlocked_aio_connect_uri (struct nbd_handle *h, const char *raw_uri)
}
}
- /* NBD user and port overrides.. */
- for (i = 0; i < queries.len; i++) {
- if (strcasecmp (queries.ptr[i].name, "nbd-user") == 0)
- nbd_user = queries.ptr[i].value;
- else if (strcasecmp (queries.ptr[i].name, "nbd-port") == 0)
- nbd_port = queries.ptr[i].value;
- }
-
- /* Set the TLS username. Always prefer nbd-user. */
- tls_username = nbd_user ? : (uri->user ? : NULL);
+ /* Set the TLS username. Always prefer tls-username parameter. */
+ if (!tls_username)
+ tls_username = uri->user;
if (tls_username && nbd_unlocked_set_tls_username (h, tls_username) == -1)
goto cleanup;
--
2.47.1

View File

@ -1,51 +0,0 @@
From 1455311720b64b51a75fbc9f4da3e4a43551df53 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 22 Apr 2025 17:30:02 +0100
Subject: [PATCH] rust: Allow cargo build --target $RUST_TARGET to be set
(cherry picked from commit 6bfae4e22aad0d21a326ea2418dbc0d59718e14e)
---
configure.ac | 2 ++
rust/Makefile.am | 6 ++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5feb6dbc..40d4f79f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -751,6 +751,8 @@ AS_IF([test "x$enable_rust" != "xno"],[
CARGO=no
])
])
+ AC_ARG_VAR([RUST_TARGET],
+ [if set, cargo build uses --target $RUST_TARGET])
],[CARGO=no])
AM_CONDITIONAL([HAVE_RUST],[test "x$CARGO" != "xno"])
diff --git a/rust/Makefile.am b/rust/Makefile.am
index a7700d69..29c29bd9 100644
--- a/rust/Makefile.am
+++ b/rust/Makefile.am
@@ -98,15 +98,17 @@ libnbd-sys/libnbd_version: Makefile
$(abs_top_builddir)/run echo $(VERSION) > libnbd-sys/libnbd_version.t
mv libnbd-sys/libnbd_version.t libnbd-sys/libnbd_version
+RUST_TARGET_PARAM := $(if $(RUST_TARGET),--target $(RUST_TARGET))
+
target/debug/liblibnbd.rlib: $(source_files)
- $(abs_top_builddir)/run $(CARGO) build
+ $(abs_top_builddir)/run $(CARGO) build $(RUST_TARGET_PARAM)
target/doc/libnbd/index.html: $(source_files)
$(abs_top_builddir)/run $(CARGO) doc
# This will actually build all the examples:
target/debug/examples/get-size: $(source_files)
- $(abs_top_builddir)/run $(CARGO) build --examples
+ $(abs_top_builddir)/run $(CARGO) build $(RUST_TARGET_PARAM) --examples
if HAVE_POD
--
2.47.1

View File

@ -0,0 +1,66 @@
From 2a5c694f7370773cb51e0d344ea8da91cbe8518e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 24 Aug 2025 16:32:18 +0100
Subject: [PATCH] tests: Add a test of tls-username in NBD URIs
This (or the previously added nbd-user) was not tested.
---
.gitignore | 1 +
tests/Makefile.am | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/.gitignore b/.gitignore
index bbe3967f..a373fc29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -230,6 +230,7 @@ Makefile.in
/tests/connect-uri-nbds-unix-tls-hostname
/tests/connect-uri-nbds-unix-tls-verify-peer-false
/tests/connect-uri-nbds-unix-psk
+/tests/connect-uri-nbds-unix-psk-tls-username
/tests/debug
/tests/debug-environment
/tests/dlopen
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8aca4c7d..e3b74a1d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -904,10 +904,12 @@ if HAVE_PSKTOOL
check_PROGRAMS += \
connect-uri-nbds-psk \
connect-uri-nbds-unix-psk \
+ connect-uri-nbds-unix-psk-tls-username \
$(NULL)
TESTS += \
connect-uri-nbds-psk \
connect-uri-nbds-unix-psk \
+ connect-uri-nbds-unix-psk-tls-username \
$(NULL)
connect_uri_nbds_psk_SOURCES = \
@@ -936,6 +938,22 @@ connect_uri_nbds_unix_psk_CPPFLAGS = \
$(NULL)
connect_uri_nbds_unix_psk_LDADD = $(top_builddir)/lib/libnbd.la
+connect_uri_nbds_unix_psk_tls_username_SOURCES = \
+ connect-uri.c \
+ requires.c requires.h pick-a-port.c pick-a-port.h \
+ $(NULL)
+connect_uri_nbds_unix_psk_tls_username_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DDEFINE_STR_AS_UNIX_SOCKET=1 \
+ -DSERVER_PARAMS='"-U", str, "--tls=require", "--tls-verify-peer", "--tls-psk=keys.psk"' \
+ -DREQUIRES="requires_nbdkit_tls_verify_peer ();" \
+ -DURI='"nbds+unix://NOTUSED@/?tls-psk-file=keys.psk&socket=%s&tls-username=alice", str' \
+ -DSKIP_GET_URI=1 \
+ $(NULL)
+connect_uri_nbds_unix_psk_tls_username_LDADD = \
+ $(top_builddir)/lib/libnbd.la \
+ $(NULL)
+
endif HAVE_PSKTOOL
endif HAVE_GNUTLS
--
2.47.1

View File

@ -0,0 +1,91 @@
From 2bd353ef0e124c11b79eb3ed15eff5c8a9738086 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 24 Aug 2025 16:27:50 +0100
Subject: [PATCH] docs: Document which NBD URI features are non-standard
Also which version of libnbd implemented each feature (unless the
feature has basically been around since the beginning).
---
generator/API.ml | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/generator/API.ml b/generator/API.ml
index c434e3e6..3ebc1912 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -1992,6 +1992,16 @@ to an NBD server listening on port 10809.
=back
+=head2 NBD URI standard
+
+L<https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md>
+documents the NBD URI standard.
+
+In the documentation below, I<Non-standard> indicates features
+supported in libnbd which are not a part of the NBD URI standard,
+meaning that other NBD URI parsers might not support them or might
+implement things differently.
+
=head2 URI scheme
The scheme is the part before the first C<:>. The following schemes
@@ -2019,6 +2029,8 @@ respectively. The C<socket> parameter is required.
=item C<nbds+vsock:>
+I<Non-standard>
+
Connect over the C<AF_VSOCK> transport, without or with
TLS respectively. You can use L<nbd_supports_vsock(3)> to
see if this build of libnbd supports C<AF_VSOCK>.
@@ -2027,7 +2039,7 @@ see if this build of libnbd supports C<AF_VSOCK>.
=item C<nbds+ssh:>
-I<Experimental>
+I<Non-standard, libnbd E<ge> 1.22>
Tunnel NBD over a Secure Shell connection. This requires
that L<ssh(1)> is installed locally, and that L<nc(1)> (from the
@@ -2069,6 +2081,8 @@ Finally the query part of the URI can contain:
=item B<nbd-port=>C<PORT>
+I<Non-standard, libnbd E<ge> 1.24>
+
Override the port number from the authority part of the URI.
For SSH transport, this specifies the port used to connect to
@@ -2083,20 +2097,28 @@ for C<+ssh>, and must not be present for the other transports.
=item B<tls-certificates=>F<DIR>
+I<Non-standard, libnbd E<ge> 1.10>
+
Set the certificates directory. See L<nbd_set_tls_certificates(3)>.
Note this is not allowed by default - see next section.
=item B<tls-psk-file=>F<PSKFILE>
+I<Non-standard>
+
Set the PSK file. See L<nbd_set_tls_psk_file(3)>. Note
this is not allowed by default - see next section.
=item B<tls-hostname=>C<SERVER>
+I<libnbd E<ge> 1.22>
+
Set the TLS hostname. See L<nbd_set_tls_hostname(3)>.
=item B<tls-username=>C<USER>
+I<Non-standard, libnbd E<ge> 1.24>
+
Override the username from the authority part of the URI.
For SSH transport, this specifies the TLS username for connecting to
--
2.47.1

View File

@ -1,318 +0,0 @@
From 3714f8912d9d1a56866df7309c4e9f0e6e60f809 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 24 Apr 2025 08:30:00 -0500
Subject: [PATCH] maint: Spelling fixes
As detected by:
$ git ls-files | xargs codespell -L Tage
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 17513dabee51b2bbbe878b06aafc50e6e2ba28de)
---
copy/file-ops.c | 2 +-
docs/libnbd-release-notes-1.18.pod | 2 +-
docs/libnbd.pod | 4 ++--
examples/copy-libev.c | 12 ++++++------
golang/aio_buffer.go | 2 +-
golang/callbacks.go | 2 +-
golang/examples/aio_copy/aio_copy.go | 4 ++--
golang/libnbd_020_aio_buffer_test.go | 2 +-
golang/libnbd_590_aio_copy_test.go | 2 +-
golang/make-dist.sh | 2 +-
info/main.c | 8 ++++----
interop/interop.c | 2 +-
ocaml/examples/asynch_copy.ml | 2 +-
ocaml/tests/test_590_aio_copy.ml | 2 +-
rust/cargo_test/README.md | 6 +++---
rust/tests/test_log/mod.rs | 2 +-
tests/closure-lifetimes.c | 2 +-
17 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/copy/file-ops.c b/copy/file-ops.c
index 491a4553..b3b04f5d 100644
--- a/copy/file-ops.c
+++ b/copy/file-ops.c
@@ -82,7 +82,7 @@ struct rw_file {
bool seek_hole_supported;
int sector_size;
- /* We try to use the most eficient zeroing first. If an efficent zero
+ /* We try to use the most efficient zeroing first. If an efficient zero
* method is not available, we disable the flag so next time we use
* the working method.
*/
diff --git a/docs/libnbd-release-notes-1.18.pod b/docs/libnbd-release-notes-1.18.pod
index 836ebe19..dc284bf4 100644
--- a/docs/libnbd-release-notes-1.18.pod
+++ b/docs/libnbd-release-notes-1.18.pod
@@ -145,7 +145,7 @@ Consistently wrap source code at 80 columns (Laszlo Ersek).
Debug messages no longer print the very verbose state transitions
inside the state machine as these are not usually useful. You can
-reenable this by defining C<-DLIBNBD_STATE_VERBOSE=1> at compile time.
+re-enable this by defining C<-DLIBNBD_STATE_VERBOSE=1> at compile time.
Completion C<.callback> methods are now always called exactly once,
and documentation is clearer on when this happens (Eric Blake).
diff --git a/docs/libnbd.pod b/docs/libnbd.pod
index 796a6f03..a7039210 100644
--- a/docs/libnbd.pod
+++ b/docs/libnbd.pod
@@ -936,7 +936,7 @@ it would cause deadlock.
=head2 Completion callbacks
-All of the asychronous commands have an optional completion callback
+All of the asynchronous commands have an optional completion callback
function that is used if the call to the asynchronous API reports
success. The completion callback is invoked when the submitted
command is eventually marked complete, after any mid-command callbacks
@@ -976,7 +976,7 @@ callback will still be valid (corresponding to the current portion of
the server's reply), and the overall command will still fail (at the
completion callback or L<nbd_aio_command_completed(3)> for an
asynchronous command, or as the result of the overall synchronous
-command). Returing C<-1> from a mid-command callback does not prevent
+command). Returning C<-1> from a mid-command callback does not prevent
that callback from being reached again, if the server sends more
mid-command replies that warrant another use of that callback. A
mid-command callback may be reached more times than expected if the
diff --git a/examples/copy-libev.c b/examples/copy-libev.c
index e8e3cda2..6c91c55d 100644
--- a/examples/copy-libev.c
+++ b/examples/copy-libev.c
@@ -3,7 +3,7 @@
*
* http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
*
- * To build it you need the libev-devel pacakge.
+ * To build it you need the libev-devel package.
*
* To run it:
*
@@ -32,7 +32,7 @@
#include <ev.h>
-/* These values depend on the enviroment tested.
+/* These values depend on the environment tested.
*
* For shared storage using direct I/O:
*
@@ -76,8 +76,8 @@ enum request_state {
IDLE, /* Not used yet. */
EXTENTS, /* Getting extents from source. */
READ, /* Read from source. */
- WRITE, /* Write to destiation. */
- ZERO, /* Write zeroes to destiation. */
+ WRITE, /* Write to destination. */
+ ZERO, /* Write zeroes to destination. */
SLEEP /* Waiting for extents completion. */
};
@@ -631,12 +631,12 @@ main (int argc, char *argv[])
debug = getenv ("COPY_LIBEV_DEBUG") != NULL;
- /* Configure soruce to report extents. */
+ /* Configure source to report extents. */
if (nbd_add_meta_context (src.nbd, LIBNBD_CONTEXT_BASE_ALLOCATION))
FAIL ("Cannot add base:allocation: %s", nbd_get_error ());
- /* Connecting is fast, so use the syncronous API. */
+ /* Connecting is fast, so use the synchronous API. */
if (nbd_connect_uri (src.nbd, argv[1]))
FAIL ("Cannot connect to source: %s", nbd_get_error ());
diff --git a/golang/aio_buffer.go b/golang/aio_buffer.go
index 3ddfce94..ff00e0a4 100644
--- a/golang/aio_buffer.go
+++ b/golang/aio_buffer.go
@@ -80,7 +80,7 @@ func (b *AioBuffer) Bytes() []byte {
// Slice creates a slice backed by the underlying C array. The slice can be
// used to access or modify the contents of the underlying array. The slice
-// must not be used after caling Free().
+// must not be used after calling Free().
func (b *AioBuffer) Slice() []byte {
if b.P == nil {
panic("Using AioBuffer after Free()")
diff --git a/golang/callbacks.go b/golang/callbacks.go
index ac53572c..f9b4958a 100644
--- a/golang/callbacks.go
+++ b/golang/callbacks.go
@@ -36,7 +36,7 @@
// - Create an exported Golang function whose job will be to retrieve
// the context and execute the callback in it
// (connErrCallback). Such a function should receive a callback ID
-// and will use it to retrive the context.
+// and will use it to retrieve the context.
//
// - Create a CGO function similar to the above function but with the
// appropriate signature to be registered as a callback in C code
diff --git a/golang/examples/aio_copy/aio_copy.go b/golang/examples/aio_copy/aio_copy.go
index 1de115b1..62756a97 100644
--- a/golang/examples/aio_copy/aio_copy.go
+++ b/golang/examples/aio_copy/aio_copy.go
@@ -62,8 +62,8 @@
)
// command keeps state of single AioPread call while the read is handled by
-// libnbd, until the command reach the front of the queue and can be writen to
-// the output.
+// libnbd, until the command reach the front of the queue and can be written
+// to the output.
type command struct {
buf libnbd.AioBuffer
ready bool
diff --git a/golang/libnbd_020_aio_buffer_test.go b/golang/libnbd_020_aio_buffer_test.go
index 5e63e27c..8addc350 100644
--- a/golang/libnbd_020_aio_buffer_test.go
+++ b/golang/libnbd_020_aio_buffer_test.go
@@ -75,7 +75,7 @@ func TestAioBuffer(t *testing.T) {
t.Fatalf("Expected %v, got %v", zeroes, buf2.Bytes())
}
- /* Crated a zeroed buffer. */
+ /* Create a zeroed buffer. */
buf3 := MakeAioBufferZero(uint(32))
defer buf.Free()
diff --git a/golang/libnbd_590_aio_copy_test.go b/golang/libnbd_590_aio_copy_test.go
index 6ae0cc63..410c8f45 100644
--- a/golang/libnbd_590_aio_copy_test.go
+++ b/golang/libnbd_590_aio_copy_test.go
@@ -86,7 +86,7 @@ func write_completed(buf AioBuffer) int {
return 1
}
-/* Copy between two libnbd handles using aynchronous I/O (AIO). */
+/* Copy between two libnbd handles using asynchronous I/O (AIO). */
func asynch_copy(t *testing.T, src *Libnbd, dst *Libnbd) {
size, _ := dst.GetSize()
diff --git a/golang/make-dist.sh b/golang/make-dist.sh
index e6c126c3..03cfc6a2 100755
--- a/golang/make-dist.sh
+++ b/golang/make-dist.sh
@@ -112,7 +112,7 @@ echo "$info" > $v_dir/$version.info
cp go.mod $v_dir/$version.mod
mv $version.zip $v_dir
-# Create the list file by amending the curent file on the server.
+# Create the list file by amending the current file on the server.
list_url=https://download.libguestfs.org/libnbd/golang/libguestfs.org/libnbd/@v/list
curl --silent --show-error "$list_url" | sort > $v_dir/list
grep -q "$version" $v_dir/list || echo "$version" >> $v_dir/list
diff --git a/info/main.c b/info/main.c
index 1ee9e329..f7da425f 100644
--- a/info/main.c
+++ b/info/main.c
@@ -130,7 +130,7 @@ main (int argc, char *argv[])
{ "can", required_argument, NULL, CAN_OPTION },
{ "cannot", required_argument, NULL, CANNOT_OPTION },
{ "can-not", required_argument, NULL, CANNOT_OPTION },
- { "cant", required_argument, NULL, CANNOT_OPTION },
+ { "can""t", required_argument, NULL, CANNOT_OPTION },
{ "color", no_argument, NULL, COLOUR_OPTION },
{ "colors", no_argument, NULL, COLOUR_OPTION },
{ "colour", no_argument, NULL, COLOUR_OPTION },
@@ -144,15 +144,15 @@ main (int argc, char *argv[])
{ "has", required_argument, NULL, CAN_OPTION },
{ "hasnot", required_argument, NULL, CANNOT_OPTION },
{ "has-not", required_argument, NULL, CANNOT_OPTION },
- { "hasnt", required_argument, NULL, CANNOT_OPTION },
+ { "hasn""t", required_argument, NULL, CANNOT_OPTION },
{ "have", required_argument, NULL, CAN_OPTION },
- { "havent", required_argument, NULL, CANNOT_OPTION },
+ { "haven""t", required_argument, NULL, CANNOT_OPTION },
{ "havenot", required_argument, NULL, CANNOT_OPTION },
{ "have-not", required_argument, NULL, CANNOT_OPTION },
{ "is", required_argument, NULL, CAN_OPTION },
{ "isnot", required_argument, NULL, CANNOT_OPTION },
{ "is-not", required_argument, NULL, CANNOT_OPTION },
- { "isnt", required_argument, NULL, CANNOT_OPTION },
+ { "isn""t", required_argument, NULL, CANNOT_OPTION },
{ "json", no_argument, NULL, JSON_OPTION },
{ "list", no_argument, NULL, 'L' },
{ "long-options", no_argument, NULL, LONG_OPTIONS },
diff --git a/interop/interop.c b/interop/interop.c
index 1ea0216e..841b7c9d 100644
--- a/interop/interop.c
+++ b/interop/interop.c
@@ -131,7 +131,7 @@ main (int argc, char *argv[])
* need to have our own log handler.
*
* Also the log levels are quite random. Level 2 doesn't show the
- * negotiated cyphersuite, but level 3+ shows excessive detail.
+ * negotiated ciphersuite, but level 3+ shows excessive detail.
*/
gnutls_global_set_log_level (2);
gnutls_global_set_log_function (tls_log);
diff --git a/ocaml/examples/asynch_copy.ml b/ocaml/examples/asynch_copy.ml
index 7132f573..8962a09e 100644
--- a/ocaml/examples/asynch_copy.ml
+++ b/ocaml/examples/asynch_copy.ml
@@ -10,7 +10,7 @@ let max_reads_in_flight = 16
let dir_is_read dir = dir land (Int32.to_int NBD.aio_direction_read) <> 0
let dir_is_write dir = dir land (Int32.to_int NBD.aio_direction_write) <> 0
-(* Copy between two libnbd handles using aynchronous I/O (AIO). *)
+(* Copy between two libnbd handles using asynchronous I/O (AIO). *)
let asynch_copy src dst =
let size = NBD.get_size dst in
diff --git a/ocaml/tests/test_590_aio_copy.ml b/ocaml/tests/test_590_aio_copy.ml
index 25105e07..b5fb5cd6 100644
--- a/ocaml/tests/test_590_aio_copy.ml
+++ b/ocaml/tests/test_590_aio_copy.ml
@@ -34,7 +34,7 @@ let bytes_written = ref 0
let dir_is_read dir = dir land (Int32.to_int NBD.aio_direction_read) <> 0
let dir_is_write dir = dir land (Int32.to_int NBD.aio_direction_write) <> 0
-(* Copy between two libnbd handles using aynchronous I/O (AIO). *)
+(* Copy between two libnbd handles using asynchronous I/O (AIO). *)
let asynch_copy src dst =
let size = NBD.get_size dst in
diff --git a/rust/cargo_test/README.md b/rust/cargo_test/README.md
index f80646b9..039cdb3e 100644
--- a/rust/cargo_test/README.md
+++ b/rust/cargo_test/README.md
@@ -1,3 +1,3 @@
-The solely purpose of this directory is to serve as a test crate for checking if Cargo is useable.
-`cargo test`, `cargo doc` and `cargo fmt` are run in the Autoconf script in this directory. If any of the commands failes,
-Cargo is assumed not to be useable and the Rust bindings will be disabled.
+The sole purpose of this directory is to serve as a test crate for checking if Cargo is usable.
+`cargo test`, `cargo doc` and `cargo fmt` are run in the Autoconf script in this directory. If any of the commands fails,
+Cargo is assumed not to be usable and the Rust bindings will be disabled.
diff --git a/rust/tests/test_log/mod.rs b/rust/tests/test_log/mod.rs
index 8dbcd79f..d3fe98eb 100644
--- a/rust/tests/test_log/mod.rs
+++ b/rust/tests/test_log/mod.rs
@@ -49,7 +49,7 @@ impl DebugLogger {
}
}
- /// Check wether a specific message has been logged.
+ /// Check whether a specific message has been logged.
pub fn contains(&self, msg: &str) -> bool {
self.entries.lock().unwrap().iter().any(|(_, x)| x == msg)
}
diff --git a/tests/closure-lifetimes.c b/tests/closure-lifetimes.c
index b9d9ce14..d6625095 100644
--- a/tests/closure-lifetimes.c
+++ b/tests/closure-lifetimes.c
@@ -156,7 +156,7 @@ main (int argc, char *argv[])
completion_callback, 0);
if (cookie == -1) NBD_ERROR;
/* read_cb_called is indeterminate at this point, as state machine
- * progress may vary based on task schduling and network speed factors.
+ * progress may vary based on task scheduling and network speed factors.
*/
assert (completion_cb_called == 0);
assert (read_cb_freed == 0);
--
2.47.1

View File

@ -0,0 +1,64 @@
From a518da9fdc54e3652f67d92d266106017145c62b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 24 Aug 2025 18:54:47 +0100
Subject: [PATCH] docs: Minor copyediting to export name documentation
---
generator/API.ml | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/generator/API.ml b/generator/API.ml
index 3ebc1912..3ab3aacb 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -478,15 +478,19 @@ handle with this information.";
permitted_states = [ Created; Negotiating ];
shortdesc = "set the export name";
longdesc = "\
-For servers which require an export name or can serve different
-content on different exports, set the C<export_name> to
-connect to. The default is the empty string C<\"\">.
+Some NBD servers can serve multiple disk images (\"exports\").
+The export is picked by the client, by requesting an export name
+during the negotiation phase. The default export is the
+empty string C<\"\">.
+Some NBD servers ignore this and serve the same content regardless.
This is only relevant when connecting to servers using the
newstyle protocol as the oldstyle protocol did not support
-export names. The NBD protocol limits export names to
-4096 bytes, but servers may not support the full length.
-The encoding of export names is always UTF-8.
+export names.
+
+The NBD protocol limits export names to 4096 bytes, but servers
+may not support the full length. The encoding of export names
+is always UTF-8.
When option mode is not in use, the export name must be set
before beginning a connection. However, when L<nbd_set_opt_mode(3)>
@@ -498,7 +502,9 @@ be used to learn details about an export before connecting.
This call may be skipped if using L<nbd_connect_uri(3)> to connect
to a URI that includes an export name.";
- see_also = [Link "get_export_name"; Link "connect_uri";
+ see_also = [Link "get_export_name";
+ Link "get_canonical_export_name";
+ Link "connect_uri";
Link "set_opt_mode"; Link "opt_go"; Link "opt_list";
Link "opt_info"];
};
@@ -603,7 +609,9 @@ C<\"\">).
Some servers are unlikely to report a canonical name unless the
client specifically hinted about wanting it, via L<nbd_set_full_info(3)>.";
example = Some "examples/server-flags.c";
- see_also = [Link "set_full_info"; Link "get_export_name";
+ see_also = [Link "set_full_info";
+ Link "set_export_name";
+ Link "get_export_name";
Link "opt_info"];
};
--
2.47.1

View File

@ -1,89 +0,0 @@
From 3d7cc461d78451cda566d6994a30ae8e1e789575 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Sat, 31 May 2025 07:37:28 -0500
Subject: [PATCH] generator: Avoid const-correctness warnings in golang
Hack the generator to add the necessary casts to discard const in a
way that shuts up the warnings from compiling wrappers.go.
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit a909e74f902bb9d1e8a4ab87ae5ccf76d4675787)
---
generator/C.ml | 10 ++++++----
generator/C.mli | 2 +-
generator/GoLang.ml | 4 ++--
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/generator/C.ml b/generator/C.ml
index ad08437c..50d22306 100644
--- a/generator/C.ml
+++ b/generator/C.ml
@@ -286,16 +286,16 @@ let print_fndecl ?wrap ?closure_style name args optargs ret =
pr "\n LIBNBD_ATTRIBUTE_NONNULL (%s);\n" (String.concat ", " nns)
let rec print_cbarg_list ?(wrap = false) ?maxcol ?types ?(parens = true)
- cbargs =
+ ?(noconst = false) cbargs =
if parens then pr "(";
if wrap then
pr_wrap ?maxcol ','
- (fun () -> print_cbarg_list' ?types cbargs)
+ (fun () -> print_cbarg_list' ?types noconst cbargs)
else
- print_cbarg_list' ?types cbargs;
+ print_cbarg_list' ?types noconst cbargs;
if parens then pr ")"
-and print_cbarg_list' ?(types = true) cbargs =
+and print_cbarg_list' ?(types = true) noconst cbargs =
if types then pr "void *";
pr "user_data";
@@ -316,6 +316,7 @@ and print_cbarg_list' ?(types = true) cbargs =
| CBArrayAndLen _ -> assert false
| CBBytesIn (n, len) ->
if types then pr "const void *";
+ if noconst then pr "(void *)";
pr "%s, " n;
if types then pr "size_t ";
pr "%s" len
@@ -331,6 +332,7 @@ and print_cbarg_list' ?(types = true) cbargs =
| CBMutable arg -> assert false
| CBString n ->
if types then pr "const char *";
+ if noconst then pr "(char *)";
pr "%s" n
| CBUInt n ->
if types then pr "unsigned ";
diff --git a/generator/C.mli b/generator/C.mli
index a4b31351..75d77276 100644
--- a/generator/C.mli
+++ b/generator/C.mli
@@ -34,7 +34,7 @@ val print_arg_list : ?wrap:bool -> ?maxcol:int ->
?closure_style:closure_style ->
API.arg list -> API.optarg list -> unit
val print_cbarg_list : ?wrap:bool -> ?maxcol:int ->
- ?types:bool -> ?parens:bool ->
+ ?types:bool -> ?parens:bool -> ?noconst:bool ->
API.cbarg list -> unit
val print_call : ?wrap:bool -> ?maxcol:int ->
?closure_style:closure_style ->
diff --git a/generator/GoLang.ml b/generator/GoLang.ml
index 3fe7cd53..1505a598 100644
--- a/generator/GoLang.ml
+++ b/generator/GoLang.ml
@@ -159,9 +159,9 @@ let print_callback_wrapper { cbname; cbargs } =
C.print_cbarg_list ~wrap:true cbargs;
pr "\n";
pr "{\n";
- pr " // golang isn't const-correct, there will be warnings here:\n";
+ pr " // golang isn't const-correct, casts avoid warnings here:\n";
pr " return %s_callback ((long *)" cbname;
- C.print_cbarg_list ~types:false ~parens:false cbargs;
+ C.print_cbarg_list ~types:false ~parens:false ~noconst:true cbargs;
pr ");\n";
pr "}\n";
pr "\n";
--
2.47.1

View File

@ -1,114 +0,0 @@
From 5fef22179c1ce7e032a773733073349d90aab155 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Sat, 31 May 2025 08:24:37 -0500
Subject: [PATCH] info: Tolerate nbdkit slop on large extents
The NBD spec currently requires servers to send aligned block extents
back if the client and server agreed to a minimum block size; but
nbdkit 1.42 has an issue where the server recognizes that a plugin
reporting an aligned extent of exactly 4G is too large for a 32-bit
block status response, and truncates it early but to an unaligned
offset (such a truncation is to an offset larger than the client's
request size). Although I'm also submitting a parallel patch to the
NBD spec to relax things on this front, and to nbdkit 1.44 to report
aligned offsets in the first place, it is still worth teaching nbdinfo
to work around this shortcoming of existing nbdkit releases. The
added test fails when applied in isolation without the corresponding
map.c changes and run against nbdkit 1.42.
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 7dc75f2542a003c7429f1af93b7ecbaef00b567c)
---
info/Makefile.am | 1 +
info/info-map-large-extent.sh | 42 +++++++++++++++++++++++++++++++++++
info/map.c | 12 +++++++++-
3 files changed, 54 insertions(+), 1 deletion(-)
create mode 100755 info/info-map-large-extent.sh
diff --git a/info/Makefile.am b/info/Makefile.am
index 21cf3f46..697bb2b6 100644
--- a/info/Makefile.am
+++ b/info/Makefile.am
@@ -49,6 +49,7 @@ info_sh_files = \
info-map-base-allocation-large.sh \
info-map-base-allocation-weird.sh \
info-map-base-allocation-zero.sh \
+ info-map-large-extent.sh \
info-map-qemu-dirty-bitmap.sh \
info-map-qemu-allocation-depth.sh \
info-map-totals.sh \
diff --git a/info/info-map-large-extent.sh b/info/info-map-large-extent.sh
new file mode 100755
index 00000000..91867275
--- /dev/null
+++ b/info/info-map-large-extent.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+# nbd client library in userspace
+# Copyright Red Hat
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+. ../tests/functions.sh
+
+set -e
+set -x
+
+requires $NBDKIT --version
+requires $NBDKIT -U - --filter=blocksize-policy data 1 --run 'test "$uri" != ""'
+
+out=info-map-large-extent.out
+cleanup_fn rm -f $out
+rm -f $out
+
+# nbdkit < 1.44 had a bug where 4G large extents would truncate larger than
+# the aligned request; whether or not nbdkit is fixed, we can work around it.
+$NBDKIT -U - data data='@4294967296 1 @^512' \
+ --filter=blocksize-policy blocksize-minimum=512 \
+ --run '$VG nbdinfo --map "$uri"' > $out
+
+cat $out
+
+diff -u - $out <<EOF
+ 0 4294967296 3 hole,zero
+4294967296 512 0 data
+EOF
diff --git a/info/map.c b/info/map.c
index 38b60c39..dfc8e911 100644
--- a/info/map.c
+++ b/info/map.c
@@ -95,8 +95,18 @@ do_map (void)
progname);
exit (EXIT_FAILURE);
}
- for (i = prev_entries_size; i < entries.len; i++)
+ for (i = prev_entries_size; i < entries.len; i++) {
+ /* nbdkit < 1.44 has a bug where even though we requested an
+ * aligned request at 4G-alignment, the result can be unaligned
+ * if it is larger than the request. The easiest workaround is
+ * to ignore the slop.
+ */
+ if (entries.ptr[i].length > max_len) {
+ entries.ptr[i].length = max_len;
+ entries.len = i + 1;
+ }
offset += entries.ptr[i].length;
+ }
}
if (!totals)
--
2.47.1

View File

@ -1,42 +0,0 @@
From 2a8dbd3840c7b01e7c544035749d3fde893923ed Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 12 Jul 2025 18:12:42 +0100
Subject: [PATCH] todo: Remove a couple of minor features that have been
implemented
Rust was implemented in 2023.
nbdcopy implemented page cache efficient operations.
(cherry picked from commit fe284d59fa0e5a85a4abac418efb8b79d81cdbb5)
---
TODO | 6 ------
1 file changed, 6 deletions(-)
diff --git a/TODO b/TODO
index e140b4fd..426b0384 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,6 @@
Explore if nbd_aio_notify_error is needed for faster response if
server goes away.
-Bindings in other languages.
- - Latest attempt at adding Rust:
- https://www.redhat.com/archives/libguestfs/2019-August/msg00416.html
-
Example code integrating with ppoll, pollfd, APR pollset (and others?).
NBD resize extension.
@@ -32,8 +28,6 @@ nbdcopy:
- Synchronous loop should be adjusted to take into account
the NBD preferred block size, as was done for multi-thread loop.
- Benchmark.
- - Better page cache usage, see nbdkit-file-plugin options
- fadvise=sequential cache=none.
- Consider io_uring if there are performance bottlenecks.
- Configurable retries in response to read or write failures.
--
2.47.1

View File

@ -1,28 +0,0 @@
From 5717b3a12ed7df158abf89fc79d030c415c1a113 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Jul 2025 12:31:33 +0100
Subject: [PATCH] ublk: Remove unused EXPECTED_VERSION
Probably we should test nbdublk --version. As we do not, this
variable was not used.
(cherry picked from commit 01f5d93d43f7eab0444c87d9d99e2ecea9bf9d44)
---
ublk/Makefile.am | 1 -
1 file changed, 1 deletion(-)
diff --git a/ublk/Makefile.am b/ublk/Makefile.am
index 667d7d0c..e06e4396 100644
--- a/ublk/Makefile.am
+++ b/ublk/Makefile.am
@@ -24,7 +24,6 @@ EXTRA_DIST = \
TESTS_ENVIRONMENT = \
LIBNBD_DEBUG=1 \
$(MALLOC_CHECKS) \
- EXPECTED_VERSION=$(VERSION) \
$(NULL)
LOG_COMPILER = $(top_builddir)/run
TESTS =
--
2.47.1

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +0,0 @@
From d19e6eb145d93c827c5acf1b4c009ff27749a205 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 7 Apr 2025 11:35:25 +0100
Subject: [PATCH] copy: Fix crash when blkhash size is not a power of 2
nbdcopy: blkhash.c:105: init_blkhash: Assertion `is_power_of_2 (blkhash_size)' failed.
The check for this was wrong, resulting in a later assertion failure
instead of an error message.
Reported-by: Vera Wu
Fixes: https://issues.redhat.com/browse/RHEL-85513
(cherry picked from commit 6c6e0822c854e423d79bef87caf1c20c5bdb5eb5)
---
copy/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/copy/main.c b/copy/main.c
index 8f943b30..9afb627c 100644
--- a/copy/main.c
+++ b/copy/main.c
@@ -220,7 +220,7 @@ main (int argc, char *argv[])
prog, "--blkhash", error, pstr);
exit (EXIT_FAILURE);
}
- if (! is_power_of_2 (blkhash_size)) {
+ if (! is_power_of_2 (i64)) {
fprintf (stderr, "%s: %s is not a power of two: %s\n",
prog, "--blkhash", &optarg[i+1]);
exit (EXIT_FAILURE);
--
2.47.1

View File

@ -1,66 +0,0 @@
From f48db2429c5aa5f56018baa18c2aa37f756975ef Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Sun, 13 Apr 2025 14:51:09 +0000
Subject: [PATCH] copy: Define block_type outside of block struct
This make the code easier to follow and maintain.
(cherry picked from commit dc5f0e6c79e7aa03ba634b71d4780f6d7d039cdd)
---
copy/blkhash.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/copy/blkhash.c b/copy/blkhash.c
index 622d8a39..526db4d2 100644
--- a/copy/blkhash.c
+++ b/copy/blkhash.c
@@ -43,26 +43,28 @@
#ifdef HAVE_GNUTLS
+/* unknown => We haven't seen this block yet. 'ptr' is NULL.
+ *
+ * zero => The block is all zeroes. 'ptr' is NULL.
+ *
+ * data => The block is all data, and we have seen the whole block,
+ * and the hash has been computed. 'ptr' points to the computed
+ * hash. 'n' is unused.
+ *
+ * incomplete => Part of the block was seen. 'ptr' points to the
+ * data block, waiting to be completed. 'n' is the number of bytes
+ * seen so far. We will compute the hash and turn this into a
+ * 'data' or 'zero' block, either when we have seen all bytes of
+ * this block, or at the end.
+ *
+ * Note that this code assumes that we are called exactly once for a
+ * range in the disk image.
+ */
+enum block_type { block_unknown = 0, block_zero, block_data, block_incomplete };
+
/* We will have one of these structs per blkhash block. */
struct block {
- /* unknown => We haven't seen this block yet. 'ptr' is NULL.
- *
- * zero => The block is all zeroes. 'ptr' is NULL.
- *
- * data => The block is all data, and we have seen the whole block,
- * and the hash has been computed. 'ptr' points to the computed
- * hash. 'n' is unused.
- *
- * incomplete => Part of the block was seen. 'ptr' points to the
- * data block, waiting to be completed. 'n' is the number of bytes
- * seen so far. We will compute the hash and turn this into a
- * 'data' or 'zero' block, either when we have seen all bytes of
- * this block, or at the end.
- *
- * Note that this code assumes that we are called exactly once for a
- * range in the disk image.
- */
- enum { block_unknown = 0, block_zero, block_data, block_incomplete } type;
+ enum block_type type;
void *ptr;
size_t n;
};
--
2.47.1

View File

@ -1,78 +0,0 @@
From 361ae3810398d0d5c3550267b0470ba235d94c32 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Sun, 13 Apr 2025 14:54:31 +0000
Subject: [PATCH] copy: Shrink struct block
Change n to uint32_t since block size bigger than 4g does not make
sense. Move the type field to the end to shrink struct size from 24
bytes to 16.
This minimizes memory usage and improves locality. For example we can
have 4 blocks in a single cache line instead of 2.5.
Testing shows up to 8% improvement in time and 33% in maximum resident
set size with 1000g empty image. With images full of zeros or images
full of non-zero bytes we see lower memory usage but no difference in
time.
| size | content | tool | source | version | memory | time |
|--------|---------|------------|--------|---------|----------|----------|
| 1000g | hole | nbdcopy | file | before | 644716k | 3.33s |
| 1000g | hole | nbdcopy | file | after | 516716k | 3.10s |
| 1000g | hole | nbdcopy | nbd | before | 388844k | 1.13s |
| 1000g | hole | nbdcopy | nbd | after | 260716k | 1.04s |
| 1000g | hole | blksum | nbd | - | 10792k | 0.29s |
| 1000g | hole | sha256sum | file | - | *2796k | *445.00s |
|--------|---------|------------|--------|---------|----------|----------|
| 10g | zero | nbdcopy | file | before | 20236k | 1.33s |
| 10g | zero | nbdcopy | file | after | 18796k | 1.32s |
| 10g | zero | nbdcopy | nbd | before | 32648k | 8.21s |
| 10g | zero | nbdcopy | nbd | after | 31416k | 8.23s |
| 10g | zero | nbdcopy | pipe | before | 19052k | 4.56s |
| 10g | zero | nbdcopy | pipe | after | 17772k | 4.56s |
| 10g | zero | blksum | nbd | - | 13948k | 3.90s |
| 10g | zero | blksum | pipe | - | 10340k | 0.55s |
| 10g | zero | sha256sum | file | - | 2796k | 4.45s |
|--------|---------|------------|--------|---------|----------|----------|
| 10g | data | nbdcopy | file | before | 20224k | 1.28s |
| 10g | data | nbdcopy | file | after | 19036k | 1.26s |
| 10g | data | nbdcopy | nbd | before | 32792k | 8.02s |
| 10g | data | nbdcopy | nbd | after | 31512k | 8.02s |
| 10g | data | nbdcopy | pipe | before | 19052k | 4.56s |
| 10g | data | nbdcopy | pipe | after | 17772k | 4.57s |
| 10g | data | blksum | nbd | - | 13888k | 3.88s |
| 10g | data | blksum | pipe | - | 12512k | 1.10s |
| 10g | data | sha256sum | file | - | 2788k | 4.49s |
* estimated based on 10g image
Measured using:
/usr/bin/time -f "memory=%Mk time=%es" ./nbdcopy --blkhash ...
Tested on Fedora 41 VM on MacBook Pro M2 Max.
(cherry picked from commit f3e1b5fe8423558b49a2b829c0fe13f601b475f2)
---
copy/blkhash.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/copy/blkhash.c b/copy/blkhash.c
index 526db4d2..41253ec8 100644
--- a/copy/blkhash.c
+++ b/copy/blkhash.c
@@ -64,9 +64,9 @@ enum block_type { block_unknown = 0, block_zero, block_data, block_incomplete };
/* We will have one of these structs per blkhash block. */
struct block {
- enum block_type type;
void *ptr;
- size_t n;
+ uint32_t n;
+ enum block_type type;
};
DEFINE_VECTOR_TYPE(blocks, struct block);
--
2.47.1

View File

@ -1,65 +0,0 @@
From d57d58ba193674bef225f0e7094b0efbaa47f680 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Sun, 13 Apr 2025 23:39:15 +0000
Subject: [PATCH] copy: Enable zero optimization for allocated extents
We optimized zero extents but computed the hash for all data blocks,
including data blocks full of zeros. Detecting a zero block is 20-100
times faster than computing a hash, depending on the machine and the
hash algorithm.
When adding a completed block, detect zero blocks and mark the block as
zero block, saving the computation of the hash and the allocation of the
digest buffer.
This optimization is already implemented for incomplete blocks.
Testing shows that computing a hash for image full of zeros is up to 7.4
times faster, and memory usage is up to 40% lower.
| size | content | tool | source | version | memory | time |
|--------|---------|------------|--------|---------|----------|----------|
| 10g | zero | nbdcopy | file | before | 20236k | 1.33s |
| 10g | zero | nbdcopy | file | after | 13212k | 0.33s |
| 10g | zero | nbdcopy | nbd | before | 32648k | 8.21s |
| 10g | zero | nbdcopy | nbd | after | 24996k | 3.32s |
| 10g | zero | nbdcopy | pipe | before | 19052k | 4.56s |
| 10g | zero | nbdcopy | pipe | after | 11244k | 0.61s |
| 10g | zero | blksum | nbd | - | 13948k | 3.90s |
| 10g | zero | blksum | pipe | - | 10340k | 0.55s |
| 10g | zero | sha256sum | file | - | 2796k | 4.45s |
|--------|---------|------------|--------|---------|----------|----------|
| 10g | data | nbdcopy | file | before | 20224k | 1.28s |
| 10g | data | nbdcopy | file | after | 20400k | 1.28s |
| 10g | data | nbdcopy | nbd | before | 32792k | 8.02s |
| 10g | data | nbdcopy | nbd | after | 32536k | 8.01s |
| 10g | data | nbdcopy | pipe | before | 19052k | 4.56s |
| 10g | data | nbdcopy | pipe | after | 19048k | 4.55s |
| 10g | data | blksum | nbd | - | 13888k | 3.88s |
| 10g | data | blksum | pipe | - | 12512k | 1.10s |
| 10g | data | sha256sum | file | - | 2788k | 4.49s |
(cherry picked from commit efbe283f9fcfc8b4e57370f71356b1bfe7ffd0a4)
---
copy/blkhash.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/copy/blkhash.c b/copy/blkhash.c
index 41253ec8..92ffafbd 100644
--- a/copy/blkhash.c
+++ b/copy/blkhash.c
@@ -213,7 +213,10 @@ set_complete_block (uint64_t blknum, const char *buf)
/* Assert that we haven't seen this block before. */
assert (b.type == block_unknown);
- if (buf) {
+ /* Detecting a zero block is 20-100 times faster than computing a hash
+ * depending on the machine and the algorithm.
+ */
+ if (buf && !is_zero (buf, blkhash_size)) {
b.type = block_data;
/* Compute the hash of the whole block now. */
--
2.47.1

View File

@ -1,39 +0,0 @@
From 4db52aea6b2c92e7dd199d5ce00f74d107f7f2f3 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Mon, 14 Apr 2025 21:40:16 +0000
Subject: [PATCH] copy: Fix corrupted hash on incomplete read
When using synchronous read with unknown file size, if the read was
shorter than request size, we updated the hash with the complete buffer,
inserting leftover bytes from the previous read into the hash.
I'm not sure if there is validation for source size and number of blocks
in the blocks vector, so this can generate a corrupted hash silently.
We probably need to validate later that the image size matches the size
of the hashed data.
I could not reproduce a corrupted hash, the issue discovered by reading
the code.
(cherry picked from commit 49cd9fbc0022c0ae5bc5d0b9dd48219dfb92b2f7)
---
copy/synch-copying.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/copy/synch-copying.c b/copy/synch-copying.c
index 09f05be2..2aa67df6 100644
--- a/copy/synch-copying.c
+++ b/copy/synch-copying.c
@@ -83,7 +83,7 @@ synch_copying (void)
size_t r;
while ((r = src->ops->synch_read (src, buf, request_size, offset)) > 0) {
- update_blkhash ((const char *) buf, offset, request_size);
+ update_blkhash ((const char *) buf, offset, r);
dst->ops->synch_write (dst, buf, r, offset);
offset += r;
progress_bar (offset, src->size);
--
2.47.1

View File

@ -1,76 +0,0 @@
From 327d819d8e8161c31da903e8171a89db97862951 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Jul 2025 12:24:12 +0100
Subject: [PATCH] build: Add ./configure --with-extra="..."
This is intended for downstream packagers to use, to provide extra
information about the version of the downstream package (such as the
RPM ENVR). This helps when identifying bugs, especially in packges
which have extensive backports (such as the RHEL packages). This is
the same as the equivalent option in nbdkit.
In Fedora we intend to use this in the spec file:
./configure --with-extra='%{name}-%{version}-%{release}'
resulting in an extra version string something like "libnbd-1.23.4-1.fc43".
(cherry picked from commit a04cda6938a9f60b26cb9aa6d55a0b4ef4d0fe76)
---
README.md | 13 +++++++++++++
configure.ac | 15 +++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/README.md b/README.md
index 0f6bcdd4..385c0e58 100644
--- a/README.md
+++ b/README.md
@@ -163,6 +163,19 @@ ### Download tarballs
http://libguestfs.org/download/libnbd
+### Downstream packagers
+
+If you are packaging libnbd, use:
+
+```
+./configure --with-extra='...'
+```
+
+providing extra information about the distribution, and/or
+distro-specific versions. It helps us with troubleshooting bug
+reports. (Also, talk to us!)
+
+
## Developers
Install the valgrind program and development headers.
diff --git a/configure.ac b/configure.ac
index 40d4f79f..6fc4342e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,6 +18,21 @@
AC_INIT([libnbd],[1.22.2])
AC_CONFIG_MACRO_DIR([m4])
+
+dnl Extra string, a freeform string defined by downstream packagers.
+dnl eg. If you are packaging libnbd for Linux distro X 1.1, you could
+dnl ./configure --with-extra="X release 1.1"
+AC_ARG_WITH([extra],
+ [AS_HELP_STRING([--with-extra=...],
+ [extra version information (for use by packagers)])],
+ [LIBNBD_VERSION_EXTRA="$withval"],
+ [LIBNBD_VERSION_EXTRA=]
+)
+AC_DEFINE_UNQUOTED([LIBNBD_VERSION_EXTRA], ["$LIBNBD_VERSION_EXTRA"],
+ [Extra version information (for use by packagers)])
+
+AC_MSG_NOTICE([libnbd version $PACKAGE_VERSION ($LIBNBD_VERSION_EXTRA)])
+
m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],[],
[m4_define([AC_USE_SYSTEM_EXTENSIONS],[])])
AC_USE_SYSTEM_EXTENSIONS
--
2.47.1

View File

@ -1,107 +0,0 @@
From e17980b7bc91eb74d2cccfcc4dc89e4dcead5609 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Jul 2025 12:26:29 +0100
Subject: [PATCH] lib: New API: nbd_get_version_extra
This new API gets the ./configure --with-extra="..." string, usually
the empty string (for upstream builds) or the package NVR (for
downstream builds).
This commit also adds a test.
(cherry picked from commit 0b7e0831912c9efcd601b4738756a0aeb948df79)
---
generator/API.ml | 26 ++++++++++++++++++++++++--
lib/handle.c | 6 ++++++
tests/get-version.c | 7 +++++++
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/generator/API.ml b/generator/API.ml
index 8ee1843a..b1932dfa 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -4172,7 +4172,7 @@ versions.";
longdesc = "\
Returns the name of the library, always C<\"libnbd\"> unless
the library was modified with another name at compile time.";
- see_also = [Link "get_version"];
+ see_also = [Link "get_version"; Link "get_version_extra"];
};
"get_version", {
@@ -4220,7 +4220,26 @@ The release number is incremented for each release along a particular
branch.
=back";
- see_also = [Link "get_package_name"];
+ see_also = [Link "get_package_name"; Link "get_version_extra"];
+ };
+
+ "get_version_extra", {
+ default_call with
+ args = []; ret = RStaticString; is_locked = false; may_set_error = false;
+ shortdesc = "return the extra version of the library";
+ longdesc = "\
+Return the extra version of libnbd. This is a freeform string
+which is set at package build time using:
+
+ ./configure --with-extra=\"...\"
+
+and it intended to be used by downstream packagers (eg. Linux distributions)
+to convey extra version information, such as the precise version of
+the libnbd RPM, C<.deb> etc.
+
+The string may be C<\"\">, indicating that no extra version information
+is available, or that this is an upstream build of libnbd.";
+ see_also = [Link "get_package_name"; Link "get_version_extra"];
};
"kill_subprocess", {
@@ -4515,6 +4534,9 @@ let first_version = [
"is_uri", (1, 22);
"get_subprocess_pid", (1, 22);
+ (* Added in 1.23.x development cycle, will be stable and supported in 1.24 *)
+ "get_version_extra", (1, 24);
+
(* These calls are proposed for a future version of libnbd, but
* have not been added to any released version so far.
"get_tls_certificates", (1, ??);
diff --git a/lib/handle.c b/lib/handle.c
index a263cc4c..ec64d601 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -566,6 +566,12 @@ nbd_unlocked_get_version (struct nbd_handle *h)
return PACKAGE_VERSION;
}
+const char *
+nbd_unlocked_get_version_extra (struct nbd_handle *h)
+{
+ return LIBNBD_VERSION_EXTRA;
+}
+
int
nbd_unlocked_kill_subprocess (struct nbd_handle *h, int signum)
{
diff --git a/tests/get-version.c b/tests/get-version.c
index b8dc5338..c195e5f5 100644
--- a/tests/get-version.c
+++ b/tests/get-version.c
@@ -53,6 +53,13 @@ main (int argc, char *argv[])
}
assert (strcmp (s, PACKAGE_VERSION) == 0);
+ s = nbd_get_version_extra (nbd);
+ if (s == NULL) {
+ fprintf (stderr, "%s\n", nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+ assert (strcmp (s, LIBNBD_VERSION_EXTRA) == 0);
+
nbd_close (nbd);
exit (EXIT_SUCCESS);
}
--
2.47.1

View File

@ -1,268 +0,0 @@
From 625a79d4eea074d8f83dc590118605d88bd9676a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 16 Jul 2025 12:27:21 +0100
Subject: [PATCH] tools: Add extra version information in the output of
--version
In tools like nbdcopy, add the extra version information, if present
to the output of commands like 'nbdcopy --version'.
For example in a downstream build you might see:
$ nbdcopy --version
nbdcopy 1.23.4 (libnbd-1.23.4-1.fc43)
libnbd 1.23.4 (libnbd-1.23.4-1.fc43)
In upstream builds or builds not using the new ./configure --with-extra
option, the output is unchanged.
(cherry picked from commit 441eadf352e387aaba687bf424cc46424507bf18)
---
common/utils/version.c | 13 +++++++++++--
copy/test-version.sh | 31 ++++++++++++++++---------------
dump/test-version.sh | 31 ++++++++++++++++---------------
fuse/test-version.sh | 31 ++++++++++++++++---------------
info/test-version.sh | 31 ++++++++++++++++---------------
sh/test-version.sh | 31 ++++++++++++++++---------------
6 files changed, 91 insertions(+), 77 deletions(-)
diff --git a/common/utils/version.c b/common/utils/version.c
index 554d3056..135c0c75 100644
--- a/common/utils/version.c
+++ b/common/utils/version.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "libnbd.h"
#include "version.h"
@@ -30,9 +31,13 @@ display_version (const char *program_name)
struct nbd_handle *nbd;
const char *package_name = NULL;
const char *version = NULL;
+ const char *version_extra = NULL;
/* The program name and the version of the binary. */
- printf ("%s %s\n", program_name, PACKAGE_VERSION);
+ printf ("%s %s", program_name, PACKAGE_VERSION);
+ if (strcmp (LIBNBD_VERSION_EXTRA, "") != 0)
+ printf (" (%s)", LIBNBD_VERSION_EXTRA);
+ printf ("\n");
/* Flush to make sure it is printed, even if the code below crashes
* for any reason.
@@ -46,9 +51,13 @@ display_version (const char *program_name)
if (nbd) {
package_name = nbd_get_package_name (nbd);
version = nbd_get_version (nbd);
+ version_extra = nbd_get_version_extra (nbd);
}
if (version) {
- printf ("%s %s\n", package_name ? package_name : PACKAGE_NAME, version);
+ printf ("%s %s", package_name ? package_name : PACKAGE_NAME, version);
+ if (strcmp (version_extra, "") != 0)
+ printf (" (%s)", version_extra);
+ printf ("\n");
fflush (stdout);
}
nbd_close (nbd);
diff --git a/copy/test-version.sh b/copy/test-version.sh
index f3bd30d4..0738f109 100755
--- a/copy/test-version.sh
+++ b/copy/test-version.sh
@@ -16,18 +16,19 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# Test that nbdcopy --version looks sane.
-
-fail=0
-output=$($VG nbdcopy --version)
-if [ $? != 0 ]; then
- echo "$0: unexpected exit status"
- fail=1
-fi
-if [ "$output" != "nbdcopy $EXPECTED_VERSION
-libnbd $EXPECTED_VERSION" ]; then
- echo "$0: unexpected output"
- fail=1
-fi
-echo "$output"
-exit $fail
+# Test that --version looks sane.
+
+. ../tests/functions.sh
+set -e
+set -x
+
+tool=nbdcopy
+
+output=test-$tool.out
+cleanup_fn rm -f $output
+
+$VG $tool --version > $output
+cat $output
+
+grep "$tool $EXPECTED_VERSION" $output
+grep "libnbd $EXPECTED_VERSION" $output
diff --git a/dump/test-version.sh b/dump/test-version.sh
index 2ef32e05..8adc0e19 100755
--- a/dump/test-version.sh
+++ b/dump/test-version.sh
@@ -16,18 +16,19 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# Test that nbddump --version looks sane.
-
-fail=0
-output=$($VG nbddump --version)
-if [ $? != 0 ]; then
- echo "$0: unexpected exit status"
- fail=1
-fi
-if [ "$output" != "nbddump $EXPECTED_VERSION
-libnbd $EXPECTED_VERSION" ]; then
- echo "$0: unexpected output"
- fail=1
-fi
-echo "$output"
-exit $fail
+# Test that --version looks sane.
+
+. ../tests/functions.sh
+set -e
+set -x
+
+tool=nbddump
+
+output=test-$tool.out
+cleanup_fn rm -f $output
+
+$VG $tool --version > $output
+cat $output
+
+grep "$tool $EXPECTED_VERSION" $output
+grep "libnbd $EXPECTED_VERSION" $output
diff --git a/fuse/test-version.sh b/fuse/test-version.sh
index 7b3e9929..18924b1f 100755
--- a/fuse/test-version.sh
+++ b/fuse/test-version.sh
@@ -16,18 +16,19 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# Test that nbdfuse --version looks sane.
-
-fail=0
-output=$($VG nbdfuse --version)
-if [ $? != 0 ]; then
- echo "$0: unexpected exit status"
- fail=1
-fi
-if [ "$output" != "nbdfuse $EXPECTED_VERSION
-libnbd $EXPECTED_VERSION" ]; then
- echo "$0: unexpected output"
- fail=1
-fi
-echo "$output"
-exit $fail
+# Test that --version looks sane.
+
+. ../tests/functions.sh
+set -e
+set -x
+
+tool=nbdfuse
+
+output=test-$tool.out
+cleanup_fn rm -f $output
+
+$VG $tool --version > $output
+cat $output
+
+grep "$tool $EXPECTED_VERSION" $output
+grep "libnbd $EXPECTED_VERSION" $output
diff --git a/info/test-version.sh b/info/test-version.sh
index 0125479e..35b1eec7 100755
--- a/info/test-version.sh
+++ b/info/test-version.sh
@@ -16,18 +16,19 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# Test that nbdinfo --version looks sane.
-
-fail=0
-output=$($VG nbdinfo --version)
-if [ $? != 0 ]; then
- echo "$0: unexpected exit status"
- fail=1
-fi
-if [ "$output" != "nbdinfo $EXPECTED_VERSION
-libnbd $EXPECTED_VERSION" ]; then
- echo "$0: unexpected output"
- fail=1
-fi
-echo "$output"
-exit $fail
+# Test that --version looks sane.
+
+. ../tests/functions.sh
+set -e
+set -x
+
+tool=nbdinfo
+
+output=test-$tool.out
+cleanup_fn rm -f $output
+
+$VG $tool --version > $output
+cat $output
+
+grep "$tool $EXPECTED_VERSION" $output
+grep "libnbd $EXPECTED_VERSION" $output
diff --git a/sh/test-version.sh b/sh/test-version.sh
index ef730ea2..5caba42c 100755
--- a/sh/test-version.sh
+++ b/sh/test-version.sh
@@ -16,18 +16,19 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-# Test that nbdsh --version looks sane.
-
-fail=0
-output=$($VG nbdsh --version)
-if [ $? != 0 ]; then
- echo "$0: unexpected exit status"
- fail=1
-fi
-if [ "$output" != "nbdsh $EXPECTED_VERSION
-libnbd $EXPECTED_VERSION" ]; then
- echo "$0: unexpected output"
- fail=1
-fi
-echo "$output"
-exit $fail
+# Test that --version looks sane.
+
+. ../tests/functions.sh
+set -e
+set -x
+
+tool=nbdsh
+
+output=test-$tool.out
+cleanup_fn rm -f $output
+
+$VG $tool --version > $output
+cat $output
+
+grep "$tool $EXPECTED_VERSION" $output
+grep "libnbd $EXPECTED_VERSION" $output
--
2.47.1

View File

@ -6,7 +6,7 @@ set -e
# directory. Use it like this:
# ./copy-patches.sh
rhel_version=10.1
rhel_version=10.2
# Check we're in the right directory.
if [ ! -f libnbd.spec ]; then

View File

@ -17,11 +17,11 @@
%global verify_tarball_signature 1
# The source directory.
%global source_directory 1.22-stable
%global source_directory 1.23-development
Name: libnbd
Version: 1.22.2
Release: 2%{?dist}
Version: 1.23.7
Release: 1%{?dist}
Summary: NBD client library in userspace
License: LGPL-2.0-or-later AND BSD-3-Clause
@ -38,25 +38,13 @@ Source2: libguestfs.keyring
Source3: copy-patches.sh
# Patches are stored in the upstream repository:
# https://gitlab.com/nbdkit/libnbd/-/commits/rhel-10.1/
# https://gitlab.com/nbdkit/libnbd/-/commits/rhel-10.2/
# Patches.
Patch0001: 0001-rust-Allow-cargo-build-target-RUST_TARGET-to-be-set.patch
#Patch0002: 0002-ci-Disable-cross-builds-of-Rust.patch
Patch0003: 0003-maint-Spelling-fixes.patch
Patch0004: 0004-generator-Avoid-const-correctness-warnings-in-golang.patch
Patch0005: 0005-info-Tolerate-nbdkit-slop-on-large-extents.patch
Patch0006: 0006-todo-Remove-a-couple-of-minor-features-that-have-bee.patch
Patch0007: 0007-ublk-Remove-unused-EXPECTED_VERSION.patch
Patch0008: 0008-copy-Add-blkhash-option.patch
Patch0009: 0009-copy-Fix-crash-when-blkhash-size-is-not-a-power-of-2.patch
Patch0010: 0010-copy-Define-block_type-outside-of-block-struct.patch
Patch0011: 0011-copy-Shrink-struct-block.patch
Patch0012: 0012-copy-Enable-zero-optimization-for-allocated-extents.patch
Patch0013: 0013-copy-Fix-corrupted-hash-on-incomplete-read.patch
Patch0014: 0014-build-Add-.-configure-with-extra.patch
Patch0015: 0015-lib-New-API-nbd_get_version_extra.patch
Patch0016: 0016-tools-Add-extra-version-information-in-the-output-of.patch
Patch0001: 0001-lib-uri.c-Replace-nbd-user-with-tls-username.patch
Patch0002: 0002-tests-Add-a-test-of-tls-username-in-NBD-URIs.patch
Patch0003: 0003-docs-Document-which-NBD-URI-features-are-non-standar.patch
Patch0004: 0004-docs-Minor-copyediting-to-export-name-documentation.patch
%if 0%{verify_tarball_signature}
BuildRequires: gnupg2
@ -96,6 +84,9 @@ BuildRequires: glib2-devel
# For bash-completion.
BuildRequires: bash-completion
%if !0%{?rhel}
BuildRequires: bash-completion-devel
%endif
# Only for running the test suite.
BuildRequires: coreutils
@ -371,6 +362,7 @@ make %{?_smp_mflags} check || {
%{python3_sitearch}/__pycache__/nbd*.py*
%{_bindir}/nbdsh
%{_mandir}/man1/nbdsh.1*
%{_mandir}/man3/libnbd-python.3*
%files -n nbdfuse
@ -386,6 +378,17 @@ make %{?_smp_mflags} check || {
%files bash-completion
%if !0%{?rhel}
%dir %{bash_completions_dir}
%{bash_completions_dir}/nbdcopy
%{bash_completions_dir}/nbddump
%{bash_completions_dir}/nbdfuse
%{bash_completions_dir}/nbdinfo
%{bash_completions_dir}/nbdsh
%if 0%{?have_ublk}
%{bash_completions_dir}/nbdublk
%endif
%else
%dir %{_datadir}/bash-completion/completions
%{_datadir}/bash-completion/completions/nbdcopy
%{_datadir}/bash-completion/completions/nbddump
@ -395,9 +398,14 @@ make %{?_smp_mflags} check || {
%if 0%{?have_ublk}
%{_datadir}/bash-completion/completions/nbdublk
%endif
%endif
%changelog
* Fri Aug 29 2025 Richard W.M. Jones <rjones@redhat.com> - 1.23.7-1
- Rebase to libnbd 1.23.7
resolves: RHEL-111243
* Wed Jul 16 2025 Richard W.M. Jones <rjones@redhat.com> - 1.22.2-2
- Rebase to libnbd 1.22.2
- Synch spec file with Fedora Rawhide.

View File

@ -1,2 +1,2 @@
SHA512 (libnbd-1.22.2.tar.gz) = 5ece4cdc41cafefbe27ddaeafc2b6b390b0cf25f38f80c1b10ec2e17ee1dcda92964891faf4abca4c8aa5827c9eec6e0b38162871e8c72b2af8e769287cd603d
SHA512 (libnbd-1.22.2.tar.gz.sig) = 0b0d6cd4e5b900aef73820f53dc87e3d7dbd80a056efbb8c6236750c91fc570b529a3bddcbb446ebbb517f279daf90d6fa7e9ffca16901b5568ac395c1b6eda2
SHA512 (libnbd-1.23.7.tar.gz) = a09a3e273829f17f5ba4b7f723afe31704ecd415f08056b308afd064358816548248cf943060acbe308ad581d4a8d236668606907bfc27f49021238a75897fc6
SHA512 (libnbd-1.23.7.tar.gz.sig) = 67025852dfcea27a6c91c1fdec8245488699d85db25cdeedb339148d1cb3ae3f9102abd54513cc334345beb7b96180b4be80ec6b9aad628a6f4b14d458b62e03