From d32b4b2509d715f951a84080cb1d5cc4f4063917 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 9 Feb 2026 21:53:14 +0000 Subject: [PATCH] Rebase to nbdkit 1.46.2 Backport nbdkit_timestamp and --port=0 fix from nbdkit 1.47. resolves: RHEL-111242 --- ...-to-C-man-pages-for-module-functions.patch | 143 ----- ...cl_ulong-to-uint64_t-before-printing.patch | 78 +++ ...mentation-for-module-functions-in-or.patch | 44 -- ...er-Add-nbdkit_debug_hexdiff-function.patch | 2 +- ...-Fix-assertion-failure-on-unaligned-.patch | 253 -------- ...ay-differences-if-D-checkwrite.showd.patch | 2 +- ...g_hexdump.pod-Document-when-hexdiff-.patch | 2 +- ...tise-minimum_io_size-64K-the-max-sup.patch | 46 -- ...g_hexdump.pod-Add-a-link-back-to-nbd.patch | 2 +- ...out-problems-with-file-plugin-block_.patch | 33 - ...=> 0006-Add-new-nbdkit_name-function.patch | 2 +- ...ulations-of-block-size-hints-for-blo.patch | 111 ---- ...ass-flags-from-.extents-through-to-..patch | 55 -- ...ic.c-Add-process_name-dummy-variable.patch | 2 +- 0008-Add-new-nbdkit_timestamp-function.patch | 577 ++++++++++++++++++ 0008-vddk-Test-with-VDDK-9.0.1.0.patch | 30 - ...igure.ac-Remove-use-of-which-command.patch | 30 - 0009-log-Use-nbdkit_timestamp.patch | 45 ++ ...in.pod-Add-a-link-to-nbdkit_timestam.patch | 29 + ...ation-about-changing-the-size-of-the.patch | 40 -- ...mmon-utils-utils.h-Add-C-boilerplate.patch | 40 -- ...stamp.pod-Fix-copy-and-paste-error-i.patch | 28 + ...out-nbdkit_timestamp-on-the-main-thr.patch | 33 + ...-Print-the-actual-bound-addresses-an.patch | 121 ++++ 0014-server-Partially-fix-port-0.patch | 214 +++++++ ...lter.sh-Remove-use-of-pick_unused_po.patch | 104 ++++ ...lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch | 109 ++++ ...-Don-t-crash-if-TCP-IP-selected-with.patch | 51 ++ ...-random-Make-block-size-configurable.patch | 416 +++++++++++++ ...se-random-Clamp-preferred-block-size.patch | 39 ++ ...e-random-blocksize.sh-Enhance-the-te.patch | 60 ++ ...e-random-blocksize.sh-Reduce-maximum.patch | 40 ++ nbdkit.spec | 49 +- sources | 4 +- 34 files changed, 1979 insertions(+), 855 deletions(-) delete mode 100644 0001-python-Link-to-C-man-pages-for-module-functions.patch create mode 100644 0001-vram-Cast-cl_ulong-to-uint64_t-before-printing.patch delete mode 100644 0002-python-Sort-documentation-for-module-functions-in-or.patch rename 0012-server-Add-nbdkit_debug_hexdiff-function.patch => 0002-server-Add-nbdkit_debug_hexdiff-function.patch (99%) delete mode 100644 0003-blocksize-policy-Fix-assertion-failure-on-unaligned-.patch rename 0013-checkwrite-Display-differences-if-D-checkwrite.showd.patch => 0003-checkwrite-Display-differences-if-D-checkwrite.showd.patch (99%) rename 0014-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch => 0004-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch (93%) delete mode 100644 0004-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch rename 0015-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch => 0005-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch (92%) delete mode 100644 0005-todo-Add-note-about-problems-with-file-plugin-block_.patch rename 0016-Add-new-nbdkit_name-function.patch => 0006-Add-new-nbdkit_name-function.patch (99%) delete mode 100644 0006-file-Change-calculations-of-block-size-hints-for-blo.patch delete mode 100644 0007-qcow2dec-Don-t-pass-flags-from-.extents-through-to-..patch rename 0017-server-test-public.c-Add-process_name-dummy-variable.patch => 0007-server-test-public.c-Add-process_name-dummy-variable.patch (94%) create mode 100644 0008-Add-new-nbdkit_timestamp-function.patch delete mode 100644 0008-vddk-Test-with-VDDK-9.0.1.0.patch delete mode 100644 0009-configure.ac-Remove-use-of-which-command.patch create mode 100644 0009-log-Use-nbdkit_timestamp.patch create mode 100644 0010-docs-nbdkit-plugin.pod-Add-a-link-to-nbdkit_timestam.patch delete mode 100644 0010-map-Fix-documentation-about-changing-the-size-of-the.patch delete mode 100644 0011-common-utils-utils.h-Add-C-boilerplate.patch create mode 100644 0011-docs-nbdkit_timestamp.pod-Fix-copy-and-paste-error-i.patch create mode 100644 0012-todo-Add-item-about-nbdkit_timestamp-on-the-main-thr.patch create mode 100644 0013-server-sockets.c-Print-the-actual-bound-addresses-an.patch create mode 100644 0014-server-Partially-fix-port-0.patch create mode 100644 0015-tests-test-ip-filter.sh-Remove-use-of-pick_unused_po.patch create mode 100644 0016-tests-test-ipv4-lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch create mode 100644 0017-server-sockets.c-Don-t-crash-if-TCP-IP-selected-with.patch create mode 100644 0018-sparse-random-Make-block-size-configurable.patch create mode 100644 0019-sparse-random-Clamp-preferred-block-size.patch create mode 100644 0020-tests-test-sparse-random-blocksize.sh-Enhance-the-te.patch create mode 100644 0021-tests-test-sparse-random-blocksize.sh-Reduce-maximum.patch diff --git a/0001-python-Link-to-C-man-pages-for-module-functions.patch b/0001-python-Link-to-C-man-pages-for-module-functions.patch deleted file mode 100644 index d449d05..0000000 --- a/0001-python-Link-to-C-man-pages-for-module-functions.patch +++ /dev/null @@ -1,143 +0,0 @@ -From a54aedafc2738a4ce5cba078a9bfa632e3ced85b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 3 Jan 2026 11:46:13 +0000 -Subject: [PATCH] python: Link to C man pages for module functions - -Since first writing the Python documentation, we now have much more -consistent coverage of the underlying C functions in separate man -pages, so link to those consistently here. - -(cherry picked from commit 458928a627718b30456c47300366137d1dc2c109) ---- - plugins/python/nbdkit-python-plugin.pod | 45 ++++++++++++++++++++----- - 1 file changed, 36 insertions(+), 9 deletions(-) - -diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod -index 0bc99bdc..87750ea1 100644 ---- a/plugins/python/nbdkit-python-plugin.pod -+++ b/plugins/python/nbdkit-python-plugin.pod -@@ -119,46 +119,62 @@ methods in the C module: - Send a debug message to stderr or syslog if verbose messages are - enabled. - -+See: L -+ - =head3 C - - Disconnect from the client. If C is C then nbdkit will - disconnect the client immediately. - -+See: L -+ - =head3 C - - Return the export name negotiated with the client as a Unicode string. - Note this should not be trusted because the client can send whatever - it wants. - -+See: L -+ - =head3 C - - Returns C if the client completed TLS authentication, or - C if the connection is plaintext. - -+See: L -+ - =head3 C - - Sleep for seconds and nanoseconds. - -+See: L -+ - =head3 C - - Parse a human-readable boolean (such as "yes" or "false"), returning - C or C. Wraps the L function. - -+See: L -+ - =head3 C - - Parse a delay or sleep (such as "10ms") into a pair (sec, nsec). - Wraps the L function. - -+See: L -+ - =head3 C - --Parse a string (such as "100M") into a size in bytes. Wraps the --L C function. -+Parse a string (such as "100M") into a size in bytes. -+ -+See: L - - =head3 C - - Parse a string (such as "100%") into a probability, returning a --floating point number. Wraps the L --function. -+floating point number. -+ -+See: L - - =head3 C, - C, -@@ -171,22 +187,27 @@ Unix domain socket, and then only on some operating systems. The - security context is usually the SELinux label, IPSEC label or - NetLabel. - -+See: L, L, -+L and L -+ - =head3 C - - Return the client TLS Distinguished Name. --See L. -+ -+See: L - - =head3 C - - Return the client certificate issuer's TLS Distinguished Name. --See L. -+ -+See: L - - =head3 C - - Read a password from a config parameter. This returns the password as --a Python C object. See L for more --information on the different ways that the C parameter can be --parsed. -+a Python C object. -+ -+See: L - - =head3 C - -@@ -201,15 +222,21 @@ C: - nbdkit.set_error(errno.EPERM) - raise RuntimeError() - -+See: L -+ - =head3 C - - Request asynchronous server shutdown. - -+See: L -+ - =head3 C - - Returns C if it is safe to interact with stdin and stdout - during the configuration phase. - -+See: L -+ - =head2 Module constants - - After C the following constants are available. These --- -2.47.3 - diff --git a/0001-vram-Cast-cl_ulong-to-uint64_t-before-printing.patch b/0001-vram-Cast-cl_ulong-to-uint64_t-before-printing.patch new file mode 100644 index 0000000..2b86f24 --- /dev/null +++ b/0001-vram-Cast-cl_ulong-to-uint64_t-before-printing.patch @@ -0,0 +1,78 @@ +From 71158f3d0091027caf8a08b0cbe825e7875e4700 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 8 Feb 2026 21:53:17 +0000 +Subject: [PATCH] vram: Cast cl_ulong to uint64_t before printing + +On i686, the code did not compile: + +vram.c: In function 'vram_dump_plugin': +vram.c:301:37: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'cl_ulong' {aka 'long long unsigned int'} [-Werror=format=] + 301 | printf ("vram_device_mem_size=%lu\n", all_devices.ptr[i].global_mem_size); + | ~~^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | long unsigned int cl_ulong {aka long long unsigned int} + | %llu +vram.c:302:50: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'cl_ulong' {aka 'long long unsigned int'} [-Werror=format=] + 302 | printf ("vram_device_max_memory_allocation=%lu\n", + | ~~^ + | | + | long unsigned int + | %llu + 303 | all_devices.ptr[i].max_mem_alloc_size); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | cl_ulong {aka long long unsigned int} +vram.c: In function 'vram_config_complete': +vram.c:364:52: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'cl_ulong' {aka 'long long unsigned int'} [-Werror=format=] + 364 | nbdkit_error ("OpenCL device '%s' has size %lu which is smaller than " + | ~~^ + | | + | long unsigned int + | %llu +...... + 367 | device.name, device.global_mem_size); + | ~~~~~~~~~~~~~~~~~~~~~~ + | | + | cl_ulong {aka long long unsigned int} +cc1: all warnings being treated as errors + +(cherry picked from commit 47c5cceeb262273c6c25c3b7f979ea90f1371e0b) +--- + plugins/vram/vram.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/plugins/vram/vram.c b/plugins/vram/vram.c +index fe8bf60e..0ed1e841 100644 +--- a/plugins/vram/vram.c ++++ b/plugins/vram/vram.c +@@ -298,9 +298,10 @@ vram_dump_plugin (void) + printf ("vram_device_vendor=%s\n", all_devices.ptr[i].vendor); + printf ("vram_device_available=%s\n", + all_devices.ptr[i].available ? "yes" : "no"); +- printf ("vram_device_mem_size=%lu\n", all_devices.ptr[i].global_mem_size); +- printf ("vram_device_max_memory_allocation=%lu\n", +- all_devices.ptr[i].max_mem_alloc_size); ++ printf ("vram_device_mem_size=%" PRIu64 "\n", ++ (uint64_t) all_devices.ptr[i].global_mem_size); ++ printf ("vram_device_max_memory_allocation=%" PRIu64 "\n", ++ (uint64_t) all_devices.ptr[i].max_mem_alloc_size); + printf ("vram_device_queue_on_device_max_size=%u\n", + all_devices.ptr[i].queue_on_device_max_size); + printf ("vram_device_queue_on_device_preferred_size=%u\n", +@@ -361,10 +362,11 @@ vram_config_complete (void) + /* Pick the size. */ + if (size >= 0) { /* size appeared on the command line */ + if (size > device.global_mem_size) { +- nbdkit_error ("OpenCL device '%s' has size %lu which is smaller than " ++ nbdkit_error ("OpenCL device '%s' has size %" PRIu64" " ++ "which is smaller than " + "the size given on the command line. To allocate the " + "maximum size, omit the size parameter.", +- device.name, device.global_mem_size); ++ device.name, (uint64_t) device.global_mem_size); + return -1; + } + } +-- +2.47.3 + diff --git a/0002-python-Sort-documentation-for-module-functions-in-or.patch b/0002-python-Sort-documentation-for-module-functions-in-or.patch deleted file mode 100644 index 33fc273..0000000 --- a/0002-python-Sort-documentation-for-module-functions-in-or.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ed37c814307ad027529b052ce7a7a3d3d15cdc58 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 3 Jan 2026 11:54:07 +0000 -Subject: [PATCH] python: Sort documentation for module functions in order - -Updates: commit 02df929dd5ac7f24a969dd4e680b8cb50bf585a7 -(cherry picked from commit e4dd09af5e0f836f4b306274517f381c23f6e461) ---- - plugins/python/nbdkit-python-plugin.pod | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/plugins/python/nbdkit-python-plugin.pod b/plugins/python/nbdkit-python-plugin.pod -index 87750ea1..9ea00f5e 100644 ---- a/plugins/python/nbdkit-python-plugin.pod -+++ b/plugins/python/nbdkit-python-plugin.pod -@@ -163,12 +163,6 @@ Wraps the L function. - - See: L - --=head3 C -- --Parse a string (such as "100M") into a size in bytes. -- --See: L -- - =head3 C - - Parse a string (such as "100%") into a probability, returning a -@@ -176,6 +170,12 @@ floating point number. - - See: L - -+=head3 C -+ -+Parse a string (such as "100M") into a size in bytes. -+ -+See: L -+ - =head3 C, - C, - C, --- -2.47.3 - diff --git a/0012-server-Add-nbdkit_debug_hexdiff-function.patch b/0002-server-Add-nbdkit_debug_hexdiff-function.patch similarity index 99% rename from 0012-server-Add-nbdkit_debug_hexdiff-function.patch rename to 0002-server-Add-nbdkit_debug_hexdiff-function.patch index e96f8ef..8d14176 100644 --- a/0012-server-Add-nbdkit_debug_hexdiff-function.patch +++ b/0002-server-Add-nbdkit_debug_hexdiff-function.patch @@ -1,4 +1,4 @@ -From 4a492dc14d14a68bd4500c95be5dca442d448b65 Mon Sep 17 00:00:00 2001 +From b546cd6870fcf16422d7fb240cb717fe4a298ce4 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Dec 2025 15:24:13 +0000 Subject: [PATCH] server: Add nbdkit_debug_hexdiff function diff --git a/0003-blocksize-policy-Fix-assertion-failure-on-unaligned-.patch b/0003-blocksize-policy-Fix-assertion-failure-on-unaligned-.patch deleted file mode 100644 index c9540d2..0000000 --- a/0003-blocksize-policy-Fix-assertion-failure-on-unaligned-.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 5610d1a4cc6da743e99973bded79cf7761ee612f Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Mon, 5 Jan 2026 10:43:46 -0600 -Subject: [PATCH] blocksize-policy: Fix assertion failure on unaligned block - status - -The blocksize-policy filter had a minor denial-of-service security -flaw, where a client could trigger the server to die from an assertion -failure by sending an unaligned block status request in violation of -NBD protocol recommendations (see the updated test within the patch -for a sample trigger). Note that libnbd makes it difficult to -trigger, as by default an unaligned request won't be sent to the -server. Additionally, use of blocksize-error-policy=error is not -impacted; and although the blocksize-policy filter defaults to an -error policy of allow, it makes less sense to use the filter in -production without opting in to blocksize-error-policy=error. - -Rather than complicating the blocksize-policy filter to manually munge -its extents requests to an aligned boundary, I opted to instead relax -the server's nbdkit_extents_aligned to support unaligned inputs by -first widening the request to alignment boundaries and then truncating -back to the original offset after at least one aligned extent is -learned. The function still stops at the first unaligned extent, -rather than trying harder to use all of the plugin's underlying -information; I have plans to add a parameter in a later patch to -optionally behave more like nbdkit_extents_full, but wanted this patch -to focus on merely the assertion failure. - -An audit of all callers of nbdkit_extents_aligned shows that only -blocksize-policy was vulnerable; the blocksize and swab filters only -ever pass in aligned values. And while at it, I made the interface -accept a 64-bit count, which makes usage easier when a client widens a -request near the 4G boundary up to an alignment boundary. - -Since the flaw is minor, I've gone ahead and made this patch public. -However, in parallel I am pursuing with Red Hat security on whether a -CVE needs to be assigned. - -Fixes: 82b60fcd ("blocksize-policy: Round extents to match minimum alignment", v1.43.11) -Signed-off-by: Eric Blake -(cherry picked from commit d4fe15c78295be3ec5f162bf41f9b9da8a669689) ---- - docs/nbdkit-filter.pod | 7 ++-- - docs/nbdkit-security.pod | 6 +++ - include/nbdkit-filter.h | 2 +- - server/extents.c | 25 +++++++---- - tests/test-blocksize-policy-extents.sh | 57 ++++++++++++++++++++++++++ - 5 files changed, 85 insertions(+), 12 deletions(-) - -diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod -index 022799f4..1bb01675 100644 ---- a/docs/nbdkit-filter.pod -+++ b/docs/nbdkit-filter.pod -@@ -1043,7 +1043,7 @@ A convenience function is provided to filters only which makes it - easier to ensure that the client only encounters aligned extents. - - int nbdkit_extents_aligned (nbdkit_next *next, -- uint32_t count, uint64_t offset, -+ uint64_t count, uint64_t offset, - uint32_t flags, uint32_t align, - struct nbdkit_extents *extents, int *err); - -@@ -1052,8 +1052,9 @@ obtained, where C is a power of 2. Anywhere the underlying - plugin returns differing extents within C bytes, this function - treats that portion of the disk as a single extent with zero and - sparse status bits determined by the intersection of all underlying --extents. It is an error to call this function with C or --C that is not already aligned. -+extents. This function supports unaligned C or C, but -+the given C must begin at C and not have any extents -+added yet. - - =head2 C<.cache> - -diff --git a/docs/nbdkit-security.pod b/docs/nbdkit-security.pod -index 64435231..38887bc6 100644 ---- a/docs/nbdkit-security.pod -+++ b/docs/nbdkit-security.pod -@@ -47,6 +47,12 @@ See the full announcement and links to mitigation, tests and fixes - here: - L - -+=head2 denial of service attack by client sending unaligned block status -+ -+See the patch here: -+L -+Full announcement and links to mitigation coming. -+ - =head1 SEE ALSO - - L. -diff --git a/include/nbdkit-filter.h b/include/nbdkit-filter.h -index ffa7fa5d..aa99af65 100644 ---- a/include/nbdkit-filter.h -+++ b/include/nbdkit-filter.h -@@ -135,7 +135,7 @@ NBDKIT_EXTERN_DECL (struct nbdkit_extents *, nbdkit_extents_full, - NBDKIT_ATTRIBUTE_NONNULL ((1, 5))); - NBDKIT_EXTERN_DECL (int, nbdkit_extents_aligned, - (nbdkit_next *next, -- uint32_t count, uint64_t offset, -+ uint64_t count, uint64_t offset, - uint32_t flags, uint32_t align, - struct nbdkit_extents *extents, int *err) - NBDKIT_ATTRIBUTE_NONNULL ((1, 6, 7))); -diff --git a/server/extents.c b/server/extents.c -index e0a2b224..8e507a94 100644 ---- a/server/extents.c -+++ b/server/extents.c -@@ -213,7 +213,7 @@ nbdkit_add_extent (struct nbdkit_extents *exts, - /* Compute aligned extents on behalf of a filter. */ - NBDKIT_DLL_PUBLIC int - nbdkit_extents_aligned (struct context *next_c, -- uint32_t count, uint64_t offset, -+ uint64_t count, uint64_t offset, - uint32_t flags, uint32_t align, - struct nbdkit_extents *exts, int *err) - { -@@ -222,22 +222,25 @@ nbdkit_extents_aligned (struct context *next_c, - struct nbdkit_extent *e, *e2; - int64_t size; - -+ assert (exts->extents.len == 0); -+ assert (exts->start == offset); -+ - size = next->get_size (next_c); - if (size == -1) { - *err = EIO; - return -1; - } -- assert (IS_ALIGNED (offset, align)); -- assert (IS_ALIGNED (count, align) || offset + count == size); -+ exts->start = ROUND_DOWN (offset, align); -+ count = MIN (ROUND_UP (offset + count, align), size) - exts->start; - - /* Perform an initial query, then scan for the first unaligned extent. */ -- if (next->extents (next_c, count, offset, flags, exts, err) == -1) -+ if (next->extents (next_c, count, exts->start, flags, exts, err) == -1) - return -1; - for (i = 0; i < exts->extents.len; ++i) { - e = &exts->extents.ptr[i]; - if (!IS_ALIGNED (e->length, align)) { - /* If the unalignment is past align, just truncate and return early */ -- if (e->offset + e->length > offset + align) { -+ if (e->offset + e->length > exts->start + align) { - e->length = ROUND_DOWN (e->length, align); - exts->extents.len = i + !!e->length; - exts->next = e->offset + e->length; -@@ -271,13 +274,13 @@ nbdkit_extents_aligned (struct context *next_c, - CLEANUP_EXTENTS_FREE struct nbdkit_extents *extents2 = NULL; - - extents2 = nbdkit_extents_new (e->offset + e->length, -- offset + align); -+ exts->start + align); - if (extents2 == NULL) { - *err = errno; - return -1; - } - if (next->extents (next_c, align - e->length, -- offset + e->length, -+ exts->start + e->length, - flags & ~NBDKIT_FLAG_REQ_ONE, - extents2, err) == -1) - return -1; -@@ -298,7 +301,13 @@ nbdkit_extents_aligned (struct context *next_c, - break; - } - } -- /* Once we get here, all extents are aligned. */ -+ /* Once we get here, all extents are aligned. Trim back to the -+ * original offset if it was unaligned. -+ */ -+ e = &exts->extents.ptr[0]; -+ e->length -= offset - exts->start; -+ e->offset += offset - exts->start; -+ exts->start = offset; - return 0; - } - -diff --git a/tests/test-blocksize-policy-extents.sh b/tests/test-blocksize-policy-extents.sh -index 46f804bb..688161ba 100755 ---- a/tests/test-blocksize-policy-extents.sh -+++ b/tests/test-blocksize-policy-extents.sh -@@ -40,6 +40,8 @@ set -u - requires_run - requires_plugin data - requires_nbdinfo -+requires nbdsh --base-allocation --version -+requires_nbdsh_uri - - files="blocksize-policy-extents.out" - rm -f $files -@@ -69,3 +71,58 @@ diff -u - blocksize-policy-extents.out < blocksize-policy-extents.out -+diff -u - blocksize-policy-extents.out < blocksize-policy-extents.out -+diff -u - blocksize-policy-extents.out < Date: Tue, 30 Dec 2025 17:09:07 +0000 Subject: [PATCH] checkwrite: Display differences if -D checkwrite.showdiffs=1 diff --git a/0014-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch b/0004-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch similarity index 93% rename from 0014-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch rename to 0004-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch index cc96598..e355925 100644 --- a/0014-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch +++ b/0004-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch @@ -1,4 +1,4 @@ -From 66b5fdc13d30025daf9e7b953eaa2f83670d094e Mon Sep 17 00:00:00 2001 +From ad67a7bbd2b596291c696e9718d68800f9a02734 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Dec 2025 21:59:24 +0000 Subject: [PATCH] docs/nbdkit_debug_hexdump.pod: Document when hexdiff was diff --git a/0004-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch b/0004-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch deleted file mode 100644 index fac338b..0000000 --- a/0004-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch +++ /dev/null @@ -1,46 +0,0 @@ -From fcda6008ff61253a2415194b85b43328be5e1910 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 7 Jan 2026 20:25:56 +0000 -Subject: [PATCH] file: Don't advertise minimum_io_size > 64K (the max - supported by NBD) - -If you create an LVM thin pool with chunk size of 128K then the kernel -will advertise /sys/block/dm-X/queue/minimum_io_size as 131072 (128K) -and the file plugin will set the minimum block size to 128K as well. -However the NBD protocol only supports a max of 64K, thus we get the -following failure: - - nbdkit: file[2]: error: plugin must set minimum block size between 1 and 64K - -This is not a hard limit and the kernel will split smaller requests, -so the simplest solution is to round down larger sizes to 64K. - -Fixes: https://issues.redhat.com/browse/RHEL-139390 -Reported-by: Nijin Ashok -Thanks: Eric Blake -See: https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#size-constraints -(cherry picked from commit 42b72dc751030c1210bc2d50f6ff0c1c1a902afc) ---- - plugins/file/file.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/plugins/file/file.c b/plugins/file/file.c -index 6a8e65c9..c69d837c 100644 ---- a/plugins/file/file.c -+++ b/plugins/file/file.c -@@ -748,6 +748,12 @@ file_open (int readonly) - if (ioctl (h->fd, BLKIOMIN, &minimum_io_size) == -1) - nbdkit_debug ("cannot get BLKIOMIN: %s: %m", h->name); - -+ /* This is the maximum that NBD supports. For Linux devices, -+ * minimum_io_size is only a hint and smaller operations work. -+ */ -+ if (minimum_io_size > 65536) -+ minimum_io_size = 65536; -+ - if (ioctl (h->fd, BLKIOOPT, &optimal_io_size) == -1) - nbdkit_debug ("cannot get BLKIOOPT: %s: %m", h->name); - else if (optimal_io_size == 0) --- -2.47.3 - diff --git a/0015-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch b/0005-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch similarity index 92% rename from 0015-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch rename to 0005-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch index d612e94..06422db 100644 --- a/0015-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch +++ b/0005-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch @@ -1,4 +1,4 @@ -From 0296eb8b718bfd5345027c307bc9df69c25fc8b4 Mon Sep 17 00:00:00 2001 +From 3a75b229eec051b473886f7a324751c89d87a35f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Dec 2025 22:01:04 +0000 Subject: [PATCH] docs/nbdkit_debug_hexdump.pod: Add a link back to diff --git a/0005-todo-Add-note-about-problems-with-file-plugin-block_.patch b/0005-todo-Add-note-about-problems-with-file-plugin-block_.patch deleted file mode 100644 index a841fe7..0000000 --- a/0005-todo-Add-note-about-problems-with-file-plugin-block_.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ca21ff4ca62b26028a7792b51189188fd5049f65 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 8 Jan 2026 21:05:23 +0000 -Subject: [PATCH] todo: Add note about problems with file plugin block_size - -(cherry picked from commit 2155ff48364a4d1a7368cf4f43ed78ce1ee47dd3) ---- - TODO.md | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/TODO.md b/TODO.md -index 8488dd95..ff72ed25 100644 ---- a/TODO.md -+++ b/TODO.md -@@ -199,6 +199,15 @@ nbdkit-file-plugin: - - For more, see comments in - https://gitlab.com/nbdkit/nbdkit/-/merge_requests/88 - -+* Block size constraints mapping between Linux hints and the -+ file_block_size callback could be improved. Our correspondent -+ writes: -+ -+ > the kernel's minimum_io_size is a hint, while logical_block_size -+ is the hard limit. nbdkit should probably be setting "minimum" to -+ logical_block_size, and using the -+ max(minimum_io_size,optimal_io_size) for "preferred" -+ - nbdkit-vram-plugin: - - * Investigate why, on AMD Radeon, trim does not immediately free Video --- -2.47.3 - diff --git a/0016-Add-new-nbdkit_name-function.patch b/0006-Add-new-nbdkit_name-function.patch similarity index 99% rename from 0016-Add-new-nbdkit_name-function.patch rename to 0006-Add-new-nbdkit_name-function.patch index 3a3e5fa..7f5020c 100644 --- a/0016-Add-new-nbdkit_name-function.patch +++ b/0006-Add-new-nbdkit_name-function.patch @@ -1,4 +1,4 @@ -From c3092c8ff0d1cd7056103f1bc855f8ab9bccc1d8 Mon Sep 17 00:00:00 2001 +From baad76a69681c0442d12010a53eb54677ff47953 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 15 Jan 2026 12:07:40 +0000 Subject: [PATCH] Add new nbdkit_name() function diff --git a/0006-file-Change-calculations-of-block-size-hints-for-blo.patch b/0006-file-Change-calculations-of-block-size-hints-for-blo.patch deleted file mode 100644 index 83fbd46..0000000 --- a/0006-file-Change-calculations-of-block-size-hints-for-blo.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 6a0ec916add4d66f1dd94a97b627a09321dda0d8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 8 Jan 2026 21:38:36 +0000 -Subject: [PATCH] file: Change calculations of block size hints for block - devices - -Related: https://issues.redhat.com/browse/RHEL-139390 -Related: commit 42b72dc751030c1210bc2d50f6ff0c1c1a902afc -Thanks: Eric Blake, Mikulas Patocka -(cherry picked from commit d0ee3c8a6dde446385c9b8e02f8d4623cb4d4184) ---- - TODO.md | 9 --------- - plugins/file/file.c | 45 ++++++++++++++++++++++++++++----------------- - 2 files changed, 28 insertions(+), 26 deletions(-) - -diff --git a/TODO.md b/TODO.md -index ff72ed25..8488dd95 100644 ---- a/TODO.md -+++ b/TODO.md -@@ -199,15 +199,6 @@ nbdkit-file-plugin: - - For more, see comments in - https://gitlab.com/nbdkit/nbdkit/-/merge_requests/88 - --* Block size constraints mapping between Linux hints and the -- file_block_size callback could be improved. Our correspondent -- writes: -- -- > the kernel's minimum_io_size is a hint, while logical_block_size -- is the hard limit. nbdkit should probably be setting "minimum" to -- logical_block_size, and using the -- max(minimum_io_size,optimal_io_size) for "preferred" -- - nbdkit-vram-plugin: - - * Investigate why, on AMD Radeon, trim does not immediately free Video -diff --git a/plugins/file/file.c b/plugins/file/file.c -index c69d837c..abd78ffc 100644 ---- a/plugins/file/file.c -+++ b/plugins/file/file.c -@@ -414,7 +414,7 @@ file_config_complete (void) - static void - file_dump_plugin (void) - { --#if defined(BLKIOMIN) && defined(BLKIOOPT) -+#if defined(BLKSSZGET) && defined(BLKIOMIN) && defined(BLKIOOPT) - printf ("file_block_size=yes\n"); - #endif - #ifdef BLKROTATIONAL -@@ -741,32 +741,43 @@ file_open (int readonly) - #endif - - h->minimum = h->preferred = h->maximum = 0; --#if defined(BLKIOMIN) && defined(BLKIOOPT) -+#if defined(BLKSSZGET) && defined(BLKIOMIN) && defined(BLKIOOPT) - if (h->is_block_device) { -- unsigned int minimum_io_size = 0, optimal_io_size = 0; -+ int logical_block_size = 0; -+ unsigned minimum_io_size = 0, optimal_io_size = 0; -+ -+ if (ioctl (h->fd, BLKSSZGET, &logical_block_size) == -1) -+ nbdkit_debug ("ioctl: %s: %s: %m", "BLKSSZGET", h->name); - - if (ioctl (h->fd, BLKIOMIN, &minimum_io_size) == -1) -- nbdkit_debug ("cannot get BLKIOMIN: %s: %m", h->name); -- -- /* This is the maximum that NBD supports. For Linux devices, -- * minimum_io_size is only a hint and smaller operations work. -- */ -- if (minimum_io_size > 65536) -- minimum_io_size = 65536; -+ nbdkit_debug ("ioctl: %s: %s: %m", "BLKIOMIN", h->name); - - if (ioctl (h->fd, BLKIOOPT, &optimal_io_size) == -1) -- nbdkit_debug ("cannot get BLKIOOPT: %s: %m", h->name); -+ nbdkit_debug ("ioctl: %s: %s: %m", "BLKIOOPT", h->name); - else if (optimal_io_size == 0) - /* All devices in the Linux kernel except for MD report optimal -- * as 0. In that case guess a good value. -+ * as 0. In that case use logical_block_size. - */ -- optimal_io_size = MAX (minimum_io_size, 4096); -+ optimal_io_size = logical_block_size; - - /* Check the values are sane before using them. */ -- if (minimum_io_size >= 512 && is_power_of_2 (minimum_io_size) && -- optimal_io_size >= minimum_io_size && is_power_of_2 (optimal_io_size)) { -- h->minimum = minimum_io_size; -- h->preferred = optimal_io_size; -+ if (logical_block_size >= 512 && is_power_of_2 (logical_block_size) && -+ minimum_io_size >= 512 && is_power_of_2 (minimum_io_size) && -+ minimum_io_size >= logical_block_size && -+ optimal_io_size >= 512 && is_power_of_2 (optimal_io_size) && -+ optimal_io_size >= logical_block_size) { -+ /* The mapping from Linux kernel settings to NBD protocol block -+ * sizes is not obvious. logical_block_size is the sector size, -+ * and anything smaller than this will cause a RMW cycle. For -+ * the preferred size, we are advised to use the largest of -+ * minimum_io_size and optimal_io_size. For this plugin maximum -+ * can be the largest that NBD can handle. -+ */ -+ -+ /* 64K is the largest minimum that the NBD protocol supports. */ -+ h->minimum = MIN (65536, logical_block_size); -+ -+ h->preferred = MAX (minimum_io_size, optimal_io_size); - h->maximum = 0xffffffff; - } - } --- -2.47.3 - diff --git a/0007-qcow2dec-Don-t-pass-flags-from-.extents-through-to-..patch b/0007-qcow2dec-Don-t-pass-flags-from-.extents-through-to-..patch deleted file mode 100644 index 08a4d3e..0000000 --- a/0007-qcow2dec-Don-t-pass-flags-from-.extents-through-to-..patch +++ /dev/null @@ -1,55 +0,0 @@ -From 121dc9e9d576bba22731dcc89fdc6b9b21a3f742 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 12 Jan 2026 14:08:25 +0000 -Subject: [PATCH] qcow2dec: Don't pass flags from .extents through to .pread - -Using the qcow2dec filter could pass the flags parameter from the -.extents callback through to the .pread callback. Since pread flags -should always be 0, but extents can contain flags, this could cause -the following failure: - - nbdkit: backend.c:666: backend_pread: Assertion `flags == 0' failed. - -This failure especially happened when the client was qemu-img convert -since that client uses req_one. It did not happen for nbdcopy. - -The relevant section of the stack trace was: - - #7 0x0000555555556440 in backend_pread (c=0x7ffff0000f70, buf=0x7ffff00ba3c0, - count=65536, offset=262144, flags=4, err=0x7ffff6cb6810) - at /home/rjones/d/nbdkit/server/backend.c:666 - #8 0x00007ffff753a436 in read_l2_entry (next=next@entry=0x7ffff0000f70, - offset=offset@entry=0, flags=flags@entry=4, - l2_present=l2_present@entry=0x7ffff6cb664f, - l2_entry=l2_entry@entry=0x7ffff6cb6650, err=err@entry=0x7ffff6cb6810) - at /home/rjones/d/nbdkit/filters/qcow2dec/qcow2dec.c:611 - #9 0x00007ffff753af83 in qcow2dec_extents (next=0x7ffff0000f70, - handle=, count32=, offset=0, flags=4, - extents=0x7ffff00775d0, err=0x7ffff6cb6810) - at /home/rjones/d/nbdkit/filters/qcow2dec/qcow2dec.c:927 - -Fixes: commit 4c5e65c9a14f2f923d56877f041023682d13e2ea -(cherry picked from commit 2f176e58c13e42d3d32ef2e42ff81fb3e74df83b) ---- - filters/qcow2dec/qcow2dec.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/filters/qcow2dec/qcow2dec.c b/filters/qcow2dec/qcow2dec.c -index 02769b69..0349cd11 100644 ---- a/filters/qcow2dec/qcow2dec.c -+++ b/filters/qcow2dec/qcow2dec.c -@@ -924,7 +924,10 @@ qcow2dec_extents (nbdkit_next *next, - uint64_t file_offset; - struct nbdkit_extent e = { .offset = offset, .length = cluster_size }; - -- if (read_l2_entry (next, offset, flags, &l2_present, &l2_entry, err) == -1) -+ /* Note: Don't pass flags here, since this is expecting pread -+ * flags (always 0). -+ */ -+ if (read_l2_entry (next, offset, 0, &l2_present, &l2_entry, err) == -1) - return -1; - - /* L2 table is unallocated. */ --- -2.47.3 - diff --git a/0017-server-test-public.c-Add-process_name-dummy-variable.patch b/0007-server-test-public.c-Add-process_name-dummy-variable.patch similarity index 94% rename from 0017-server-test-public.c-Add-process_name-dummy-variable.patch rename to 0007-server-test-public.c-Add-process_name-dummy-variable.patch index 30e30c7..8ce8b7d 100644 --- a/0017-server-test-public.c-Add-process_name-dummy-variable.patch +++ b/0007-server-test-public.c-Add-process_name-dummy-variable.patch @@ -1,4 +1,4 @@ -From 67ce065641e4da313e54b80352c6d7a8599d08ab Mon Sep 17 00:00:00 2001 +From dad58135284cb5e884bccdc8868b1ba2e245a3d3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 15 Jan 2026 15:02:53 +0000 Subject: [PATCH] server/test-public.c: Add process_name dummy variable diff --git a/0008-Add-new-nbdkit_timestamp-function.patch b/0008-Add-new-nbdkit_timestamp-function.patch new file mode 100644 index 0000000..39057c4 --- /dev/null +++ b/0008-Add-new-nbdkit_timestamp-function.patch @@ -0,0 +1,577 @@ +From 630f3eecbecab4c5d46c84fe48c112b503effb5a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 29 Jan 2026 10:24:58 +0000 +Subject: [PATCH] Add new nbdkit_timestamp() function + +This function can be used to flexibly add timestamps to debug and +error messages (or any kind of logging). + +(cherry picked from commit 773d958c8f2a5043053d385b8bfe287c43ee63d4) +--- + .gitignore | 1 + + docs/Makefile.am | 7 +++ + docs/nbdkit_debug.pod | 4 ++ + docs/nbdkit_error.pod | 6 +++ + docs/nbdkit_timestamp.pod | 75 ++++++++++++++++++++++++++++++++ + include/nbdkit-common.h | 1 + + server/internal.h | 1 + + server/nbdkit.syms | 1 + + server/public.c | 55 +++++++++++++++++++++++- + server/test-public.c | 6 +++ + server/threadlocal.c | 20 +++++++++ + tests/Makefile.am | 25 +++++++++++ + tests/test-timestamp-plugin.c | 81 +++++++++++++++++++++++++++++++++++ + tests/test-timestamp.sh | 61 ++++++++++++++++++++++++++ + 14 files changed, 343 insertions(+), 1 deletion(-) + create mode 100644 docs/nbdkit_timestamp.pod + create mode 100644 tests/test-timestamp-plugin.c + create mode 100755 tests/test-timestamp.sh + +diff --git a/.gitignore b/.gitignore +index 55d971e6..2b86a056 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -48,6 +48,7 @@ docs/nbdkit_realpath.3 + docs/nbdkit_shutdown.3 + docs/nbdkit_stdio_safe.3 + docs/nbdkit_strdup_intern.3 ++docs/nbdkit_timestamp.3 + docs/nbdkit-tracing.3 + filters/*/*.1 + plugins/*/*.1 +diff --git a/docs/Makefile.am b/docs/Makefile.am +index a43b13ed..742f5460 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -85,6 +85,7 @@ EXTRA_DIST = \ + nbdkit_shutdown.pod \ + nbdkit_stdio_safe.pod \ + nbdkit_strdup_intern.pod \ ++ nbdkit_timestamp.pod \ + nbdkit-tls.pod \ + nbdkit-tracing.pod \ + synopsis.txt \ +@@ -176,6 +177,7 @@ generated_mans = \ + nbdkit_shutdown.3 \ + nbdkit_stdio_safe.3 \ + nbdkit_strdup_intern.3 \ ++ nbdkit_timestamp.3 \ + nbdkit-tls.1 \ + nbdkit-tracing.3 \ + $(NULL) +@@ -348,6 +350,11 @@ nbdkit_strdup_intern.3: nbdkit_strdup_intern.pod $(top_builddir)/podwrapper.pl + --html $(top_builddir)/html/$@.html \ + $< + ++nbdkit_timestamp.3: nbdkit_timestamp.pod $(top_builddir)/podwrapper.pl ++ $(PODWRAPPER) --section=3 --man $@ \ ++ --html $(top_builddir)/html/$@.html \ ++ $< ++ + nbdkit-tls.1: nbdkit-tls.pod $(top_builddir)/podwrapper.pl + $(PODWRAPPER) --section=1 --man $@ \ + --html $(top_builddir)/html/$@.html \ +diff --git a/docs/nbdkit_debug.pod b/docs/nbdkit_debug.pod +index d58d9bda..ee1ba719 100644 +--- a/docs/nbdkit_debug.pod ++++ b/docs/nbdkit_debug.pod +@@ -25,6 +25,9 @@ and also support the glibc extension of a single C<%m> in a format + string expanding to C, even on platforms that don't + support that natively. + ++C does not timestamp messages. To add timestamps, see ++L. ++ + =head1 LANGUAGE BINDINGS + + In L: +@@ -60,6 +63,7 @@ L, + L, + L, + L, ++L, + L, + L. + +diff --git a/docs/nbdkit_error.pod b/docs/nbdkit_error.pod +index 2b41a4f0..d9283baa 100644 +--- a/docs/nbdkit_error.pod ++++ b/docs/nbdkit_error.pod +@@ -61,6 +61,11 @@ The default is to send error messages to stderr, unless nbdkit forks + into the background in which case they are sent to syslog. For more + information read the description in L. + ++=head2 Timestamps ++ ++C does not timestamp messages. To add timestamps, see ++L. ++ + =head1 LANGUAGE BINDINGS + + Most language bindings do not expose these functions explicitly. +@@ -78,6 +83,7 @@ C was added in nbdkit 1.2. + + L, + L, ++L, + L, + L. + +diff --git a/docs/nbdkit_timestamp.pod b/docs/nbdkit_timestamp.pod +new file mode 100644 +index 00000000..2662b204 +--- /dev/null ++++ b/docs/nbdkit_timestamp.pod +@@ -0,0 +1,75 @@ ++=head1 NAME ++ ++nbdkit_timestamp - generate a timestamp for log messages ++ ++=head1 SYNOPSIS ++ ++ #include ++ ++ const char *nbdkit_timestamp (void); ++ ++=head1 DESCRIPTION ++ ++C generates a timestamp as a printable string which ++may be added to debug or error messages (see L, ++L). ++ ++It can be used like this: ++ ++ nbdkit_debug ("%s: this is a debug message", nbdkit_timestamp ()); ++ ++which would produce a debug message like this: ++ ++ debug: 2026-01-01 12:00:00.000333: this is a debug message ++ ++The timestamps show the wallclock time in approximately ISO 8601 ++format, but less ugly. They are always shown in UTC, in 24 hour ++notation, to the nearest microsecond. (On Windows, timestamps use the ++same format but are rounded to the nearest millisecond.) ++ ++You can also separate the nbdkit_timestamp() call from the place where ++it is used, allowing you to accurately timestamp, for example, the ++point when a system call was invoked: ++ ++ const char *ts = nbdkit_timestamp (); ++ int r = pwrite (fd, ...); ++ if (r == -1) { ++ /* The error message shows the time that pwrite started. */ ++ nbdkit_error ("%s: pwrite: %m", ts); ++ return -1; ++ } ++ ++=head1 RETURN VALUE ++ ++The function returns a constant string allocated in thread-local ++storage. The string is valid until the next call to ++C in the same thread. ++ ++It never returns C. In the (very unlikely) case that there was ++an error generating the timestamp, the string C<"!"> is returned. ++ ++=begin comment ++ ++=head1 LANGUAGE BINDINGS ++ ++=end comment ++ ++=head1 HISTORY ++ ++C was added in nbdkit 1.48. ++ ++=head1 SEE ALSO ++ ++L, ++L, ++L, ++L, ++L. ++ ++=head1 AUTHORS ++ ++Richard W.M. Jones ++ ++=head1 COPYRIGHT ++ ++Copyright Red Hat +diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h +index 4b42c9d7..230365db 100644 +--- a/include/nbdkit-common.h ++++ b/include/nbdkit-common.h +@@ -205,6 +205,7 @@ NBDKIT_EXTERN_DECL (char *, nbdkit_peer_tls_issuer_dn, + NBDKIT_EXTERN_DECL (void, nbdkit_shutdown, (void)); + NBDKIT_EXTERN_DECL (void, nbdkit_disconnect, (int force)); + NBDKIT_EXTERN_DECL (const char *, nbdkit_name, (void)); ++NBDKIT_EXTERN_DECL (const char *, nbdkit_timestamp, (void)); + + NBDKIT_EXTERN_DECL (const char *, nbdkit_strdup_intern, + (const char *str) +diff --git a/server/internal.h b/server/internal.h +index f10de3ef..511ec536 100644 +--- a/server/internal.h ++++ b/server/internal.h +@@ -633,6 +633,7 @@ extern int threadlocal_get_errno (void); + extern void threadlocal_set_last_error (char *msg); + extern void threadlocal_clear_last_error (void); + extern const char *threadlocal_get_last_error (void); ++extern int threadlocal_set_timestamp (char *timestamp); + extern void *threadlocal_buffer (size_t size); + extern void threadlocal_set_conn (struct connection *conn); + extern struct connection *threadlocal_get_conn (void); +diff --git a/server/nbdkit.syms b/server/nbdkit.syms +index bf6bb378..fb732e9e 100644 +--- a/server/nbdkit.syms ++++ b/server/nbdkit.syms +@@ -93,6 +93,7 @@ + nbdkit_stdio_safe; + nbdkit_strdup_intern; + nbdkit_strndup_intern; ++ nbdkit_timestamp; + nbdkit_use_default_export; + nbdkit_vdebug; + nbdkit_verror; +diff --git a/server/public.c b/server/public.c +index d08930dd..8d0b69d3 100644 +--- a/server/public.c ++++ b/server/public.c +@@ -47,9 +47,11 @@ + #include + #include + #include +-#include + #include + ++#include ++#include ++ + #ifdef HAVE_TERMIOS_H + #include + #endif +@@ -1226,3 +1228,54 @@ nbdkit_name (void) + { + return process_name; + } ++ ++NBDKIT_DLL_PUBLIC const char * ++nbdkit_timestamp (void) ++{ ++ char *timestamp = NULL; ++ const size_t len = 64; ++ ++ timestamp = malloc (len); ++ if (timestamp == NULL) ++ goto err; ++ ++#ifndef WIN32 ++ struct timeval tv; ++ struct tm tm; ++ size_t n; ++ ++ if (gettimeofday (&tv, NULL) == -1) ++ goto err; ++ gmtime_r (&tv.tv_sec, &tm); ++ ++ n = strftime (timestamp, len, "%F %T", &tm); ++ if (n == 0) ++ goto err; ++ snprintf (timestamp + n, len - n, ".%06" PRIu64, (uint64_t) tv.tv_usec); ++#else /* WIN32 */ ++ /* Windows doesn't have thread-safe gmtime, or the strftime %F and ++ * %T formatters. Let's try to do this in a Windows native way. ++ * Windows SYSTEMTIME only returns milliseconds. ++ */ ++ SYSTEMTIME st; ++ GetSystemTime (&st); ++ snprintf (timestamp, len, "%04d-%02d-%02d %02d:%02d:%02d.%03d000", ++ st.wYear, st.wMonth, st.wDay, ++ st.wHour, st.wMinute, st.wSecond, ++ st.wMilliseconds); ++#endif /* WIN32 */ ++ ++ /* Store the timestamp in thread-local storage. This passes ++ * ownership to threadlocal which will free it either on the next ++ * call or if the thread exits. This can fail (although it would be ++ * extremely unusual), and in that case we have to return something. ++ */ ++ if (threadlocal_set_timestamp (timestamp) == -1) ++ goto err; ++ ++ return timestamp; ++ ++ err: ++ free (timestamp); ++ return "!"; ++} +diff --git a/server/test-public.c b/server/test-public.c +index 3ef530ff..0edd3f49 100644 +--- a/server/test-public.c ++++ b/server/test-public.c +@@ -92,6 +92,12 @@ threadlocal_get_context (void) + abort (); + } + ++int ++threadlocal_set_timestamp (char *timestamp) ++{ ++ abort (); ++} ++ + conn_status + connection_get_status (void) + { +diff --git a/server/threadlocal.c b/server/threadlocal.c +index 74a3c4e5..108b9793 100644 +--- a/server/threadlocal.c ++++ b/server/threadlocal.c +@@ -57,6 +57,7 @@ struct threadlocal { + size_t instance_num; /* Can be 0. */ + int err; + char *last_error; /* Can be NULL. */ ++ char *timestamp; /* Can be NULL. */ + void *buffer; /* Can be NULL. */ + size_t buffer_size; + struct connection *conn; /* Can be NULL. */ +@@ -72,6 +73,7 @@ free_threadlocal (void *threadlocalv) + + free (threadlocal->name); + free (threadlocal->last_error); ++ free (threadlocal->timestamp); + free (threadlocal->buffer); + free (threadlocal); + } +@@ -216,6 +218,24 @@ threadlocal_get_last_error (void) + return threadlocal ? threadlocal->last_error : NULL; + } + ++/* Set the timestamp. Ownership is passed to TLS. This is used by ++ * nbdkit_timestamp(). Calling this frees any existing timestamp in ++ * the thread. ++ */ ++int ++threadlocal_set_timestamp (char *timestamp) ++{ ++ struct threadlocal *threadlocal = pthread_getspecific (threadlocal_key); ++ ++ if (threadlocal) { ++ free (threadlocal->timestamp); ++ threadlocal->timestamp = timestamp; ++ return 0; ++ } ++ else ++ return -1; ++} ++ + /* Return the single pread/pwrite buffer for this thread. The buffer + * size is increased to ‘size’ bytes if required. + * +diff --git a/tests/Makefile.am b/tests/Makefile.am +index f0665926..8b7cb851 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -273,6 +273,7 @@ TESTS += \ + test-name.sh \ + test-no-name.sh \ + test-name-plugin.sh \ ++ test-timestamp.sh \ + test-dump-plugin-example1.sh \ + test-dump-plugin.sh \ + test-dump-plugin-example2.sh \ +@@ -413,6 +414,7 @@ EXTRA_DIST += \ + test-timeout.sh \ + test-timeout.py \ + test-timeout-cancel.sh \ ++ test-timestamp.sh \ + test-tls-priority.sh \ + test-tls-psk.sh \ + test-tls.sh \ +@@ -603,6 +605,29 @@ test_name_plugin_la_LDFLAGS = \ + $(NULL) + test_name_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) + ++# check_LTLIBRARIES won't build a shared library (see automake manual). ++# So we have to do this and add a dependency. ++noinst_LTLIBRARIES += \ ++ test-timestamp-plugin.la \ ++ $(NULL) ++test-timestamp.sh: test-timestamp-plugin.la ++ ++test_timestamp_plugin_la_SOURCES = \ ++ test-timestamp-plugin.c \ ++ $(top_srcdir)/include/nbdkit-plugin.h \ ++ $(NULL) ++test_timestamp_plugin_la_CPPFLAGS = \ ++ -I$(top_srcdir)/include \ ++ -I$(top_builddir)/include \ ++ $(NULL) ++test_timestamp_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) ++# For use of the -rpath option, see: ++# https://lists.gnu.org/archive/html/libtool/2007-07/msg00067.html ++test_timestamp_plugin_la_LDFLAGS = \ ++ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ ++ $(NULL) ++test_timestamp_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) ++ + endif HAVE_PLUGINS + + # Test the header files can be included on their own. +diff --git a/tests/test-timestamp-plugin.c b/tests/test-timestamp-plugin.c +new file mode 100644 +index 00000000..f7efe270 +--- /dev/null ++++ b/tests/test-timestamp-plugin.c +@@ -0,0 +1,81 @@ ++/* nbdkit ++ * Copyright Red Hat ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * * Neither the name of Red Hat nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++/* This plugin tests nbdkit_timestamp(). ++ * ++ * The corresponding test is 'test-timestamp.sh'. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#define NBDKIT_API_VERSION 2 ++#include ++ ++static void * ++timestamp_open (int readonly) ++{ ++ nbdkit_debug ("%s: timestamped open", nbdkit_timestamp ()); ++ return NBDKIT_HANDLE_NOT_NEEDED; ++} ++ ++static int64_t ++timestamp_get_size (void *handle) ++{ ++ return 1024*1024*1024; ++} ++ ++#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL ++ ++static int ++timestamp_pread (void *handle, void *buf, uint32_t count, uint64_t offset, ++ uint32_t flags) ++{ ++ const char *ts = nbdkit_timestamp (); ++ memset (buf, 0, count); ++ nbdkit_debug ("%s: timestamped memset", ts); ++ ++ return 0; ++} ++ ++static struct nbdkit_plugin plugin = { ++ .name = "timestamp", ++ .version = PACKAGE_VERSION, ++ .open = timestamp_open, ++ .get_size = timestamp_get_size, ++ .pread = timestamp_pread, ++}; ++ ++NBDKIT_REGISTER_PLUGIN (plugin) +diff --git a/tests/test-timestamp.sh b/tests/test-timestamp.sh +new file mode 100755 +index 00000000..5479fd37 +--- /dev/null ++++ b/tests/test-timestamp.sh +@@ -0,0 +1,61 @@ ++#!/usr/bin/env bash ++# nbdkit ++# Copyright Red Hat ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions are ++# met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in the ++# documentation and/or other materials provided with the distribution. ++# ++# * Neither the name of Red Hat nor the names of its contributors may be ++# used to endorse or promote products derived from this software without ++# specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ++# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR ++# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++# SUCH DAMAGE. ++ ++# Test the nbdkit_timestamp() API. ++ ++source ./functions.sh ++set -e ++set -x ++set -u ++ ++requires_run ++requires_nbdcopy ++ ++plugin=.libs/test-timestamp-plugin.$SOEXT ++requires test -f $plugin ++ ++out=timestamp.out ++cleanup_fn rm -f "$out" ++rm -f "$out" ++ ++# Print the current date for comparison when checking the log. ++date ++ ++# The plugin is large (but empty). Run nbdcopy which will invoke ++# the .pread method in the plugin in parallel. ++nbdkit -fv "$plugin" --run 'nbdcopy "$uri" null:' 2> $out ++cat $out ++ ++# We are mainly interested that (a) the plugin nor nbdkit crash and ++# (b) that valgrind checks pass. So here we only need to check that ++# some timestamps were generated in the log. ++grep 'debug: [[:digit:]]\{4\}-[[:digit:]]\{2\}-[[:digit:]]\{2\} [[:digit:]]\{2\}:[[:digit:]]\{2\}:[[:digit:]]\{2\}\.[[:digit:]]\{6\}: timestamped' $out +-- +2.47.3 + diff --git a/0008-vddk-Test-with-VDDK-9.0.1.0.patch b/0008-vddk-Test-with-VDDK-9.0.1.0.patch deleted file mode 100644 index 3b73332..0000000 --- a/0008-vddk-Test-with-VDDK-9.0.1.0.patch +++ /dev/null @@ -1,30 +0,0 @@ -From cb6383e611a070e180200e05980e5efd4f72ec3b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 12 Jan 2026 19:54:31 +0000 -Subject: [PATCH] vddk: Test with VDDK 9.0.1.0 - -There are almost no changes in this version compared to 9.0.0.0. - -Reported-by: Ajay Victor -Fixes: https://issues.redhat.com/browse/RHEL-140615 -(cherry picked from commit e43f9aab6bba2d31dd365f14fddc653926c662d7) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 4685ba6b..2d34fe14 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -439,7 +439,7 @@ This is also the first version that supported the - C API. This is used to provide - sparseness (extent) information over NBD. - --=item VDDK 9.0.0.0 (released Jun 2025) -+=item VDDK 9.0.1.0 (released Sep 2025) - - This is the latest version of VDDK that we have tested at the time of - writing, but the plugin should work with future versions. --- -2.47.3 - diff --git a/0009-configure.ac-Remove-use-of-which-command.patch b/0009-configure.ac-Remove-use-of-which-command.patch deleted file mode 100644 index 96628a3..0000000 --- a/0009-configure.ac-Remove-use-of-which-command.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 70346d26c037809c1cf1ac35c45ac95d0840389f Mon Sep 17 00:00:00 2001 -From: Christopher Byrne -Date: Wed, 14 Jan 2026 18:50:03 -0600 -Subject: [PATCH] configure.ac: Remove use of "which" command - -It's not a required command, use "command -v" which is POSIX shell -compliant. See https://bugs.gentoo.org/646588 . - -Signed-off-by: Christopher Byrne -(cherry picked from commit 59e0f6d4537b67c37d0f9fc7c8d819208ce72929) ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 64aa44a5..7a19fb95 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -205,7 +205,7 @@ AC_PROG_RANLIB - dnl Bash must be at least version 4. If it is too old, fail hard - dnl with a good diagnostic. Note macOS ships an ancient version - dnl of bash (https://gitlab.com/nbdkit/nbdkit/-/issues/21) --bash=`which bash` -+bash=$(command -v bash) - AC_MSG_CHECKING([for the major version of $bash]) - bash_major=`bash -c 'echo ${BASH_VERSINFO:-0}'` - AC_MSG_RESULT([$bash_major]) --- -2.47.3 - diff --git a/0009-log-Use-nbdkit_timestamp.patch b/0009-log-Use-nbdkit_timestamp.patch new file mode 100644 index 0000000..3438a9a --- /dev/null +++ b/0009-log-Use-nbdkit_timestamp.patch @@ -0,0 +1,45 @@ +From f1c763c8e15e23be656836e4b8ed740434776c3e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 29 Jan 2026 11:14:49 +0000 +Subject: [PATCH] log: Use nbdkit_timestamp() + +After adding the new public nbdkit_timestamp function we can replace +the open-coded timestamp generation in the log filter. Note the +format is identical (since the nbdkit_timestamp code was copied from +here). + +(cherry picked from commit 2942d8381dcbe573093e819360b5b1d5d38b80b7) +--- + filters/log/output.c | 16 +--------------- + 1 file changed, 1 insertion(+), 15 deletions(-) + +diff --git a/filters/log/output.c b/filters/log/output.c +index 4a116046..72a0ba3c 100644 +--- a/filters/log/output.c ++++ b/filters/log/output.c +@@ -60,21 +60,7 @@ static void + to_file (struct handle *h, log_id_t id, const char *act, enum type type, + const char *fmt, va_list args) + { +- struct timeval tv; +- struct tm tm; +- char timestamp[27] = "Time unknown"; +- +- /* Logging is best effort, so ignore failure to get timestamp */ +- if (!gettimeofday (&tv, NULL)) { +- size_t s; +- +- gmtime_r (&tv.tv_sec, &tm); +- s = strftime (timestamp, sizeof timestamp - sizeof ".000000" + 1, +- "%F %T", &tm); +- assert (s); +- snprintf (timestamp + s, sizeof timestamp - s, ".%06ld", +- 0L + tv.tv_usec); +- } ++ const char *timestamp = nbdkit_timestamp (); + + #ifdef HAVE_FLOCKFILE + flockfile (logfile); +-- +2.47.3 + diff --git a/0010-docs-nbdkit-plugin.pod-Add-a-link-to-nbdkit_timestam.patch b/0010-docs-nbdkit-plugin.pod-Add-a-link-to-nbdkit_timestam.patch new file mode 100644 index 0000000..7264d32 --- /dev/null +++ b/0010-docs-nbdkit-plugin.pod-Add-a-link-to-nbdkit_timestam.patch @@ -0,0 +1,29 @@ +From 69e58c8e3f98c845cc13884d3ce4b6e768d2afb7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 29 Jan 2026 15:18:12 +0000 +Subject: [PATCH] docs/nbdkit-plugin.pod: Add a link to nbdkit_timestamp(3) + +The plugin page should link to every API page, and I forgot to add a +new link to nbdkit_timestamp(3). + +Fixes: commit 773d958c8f2a5043053d385b8bfe287c43ee63d4 +(cherry picked from commit a1a659645fa39cdba0996cb57673033be1a17385) +--- + docs/nbdkit-plugin.pod | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod +index 41f65908..3a5dc4a7 100644 +--- a/docs/nbdkit-plugin.pod ++++ b/docs/nbdkit-plugin.pod +@@ -1661,6 +1661,7 @@ L, + L, + L, + L, ++L, + L, + L, + L. +-- +2.47.3 + diff --git a/0010-map-Fix-documentation-about-changing-the-size-of-the.patch b/0010-map-Fix-documentation-about-changing-the-size-of-the.patch deleted file mode 100644 index 1e96a9c..0000000 --- a/0010-map-Fix-documentation-about-changing-the-size-of-the.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0282cc8d29c789a0872eaa7f364fa948167cfb8f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 17 Jan 2026 20:57:22 +0000 -Subject: [PATCH] map: Fix documentation about changing the size of the disk - -Since map-size was implemented in commit 058710d26c ("map: Implement -map-size feature") this filter can in fact change the size of the -disk. However using nbdkit-truncate-filter is still better. - -Fixes: commit 058710d26c94904535135a9b85f788cd9bcc0477 -(cherry picked from commit 84edd687b0080e693aafc97592efb18947b7a8ab) ---- - filters/map/nbdkit-map-filter.pod | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/filters/map/nbdkit-map-filter.pod b/filters/map/nbdkit-map-filter.pod -index 8fce70ce..92e4a92f 100644 ---- a/filters/map/nbdkit-map-filter.pod -+++ b/filters/map/nbdkit-map-filter.pod -@@ -10,11 +10,12 @@ nbdkit-map-filter - remap disk blocks - =head1 DESCRIPTION - - C is an L filter which can remap parts --of the underlying plugin, such as moving a sector or partition. To --select part of a disk, use L instead. To --select a partition, use L. This filter --cannot change the size of the disk, use L --to do that. -+of the underlying plugin, such as moving a sector or partition. -+ -+To select part of a disk, use L instead. To -+select a partition, use L. Although this -+filter can change the size of the disk, L -+is easier to use. - - =head1 EXAMPLES - --- -2.47.3 - diff --git a/0011-common-utils-utils.h-Add-C-boilerplate.patch b/0011-common-utils-utils.h-Add-C-boilerplate.patch deleted file mode 100644 index dfd828d..0000000 --- a/0011-common-utils-utils.h-Add-C-boilerplate.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b3502c4e9294ba5b760ca54312b1cc73eab1883d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 18 Jan 2026 18:33:38 +0000 -Subject: [PATCH] common/utils/utils.h: Add C++ boilerplate - -Allow these utility functions to be called from internal plugins -written in C++. - -(cherry picked from commit 3db92f66452525309422329304f25f61fa807709) ---- - common/utils/utils.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/common/utils/utils.h b/common/utils/utils.h -index 20cf0abc..3f9e4512 100644 ---- a/common/utils/utils.h -+++ b/common/utils/utils.h -@@ -33,6 +33,10 @@ - #ifndef NBDKIT_UTILS_H - #define NBDKIT_UTILS_H - -+#ifdef __cplusplus -+extern "C" { -+#endif -+ - #include - - extern void shell_quote (const char *str, FILE *fp); -@@ -54,4 +58,8 @@ extern ssize_t full_pwrite (int fd, const void *buf, size_t count, - extern int64_t device_size (int fd, const struct stat *statbuf); - #endif - -+#ifdef __cplusplus -+} -+#endif -+ - #endif /* NBDKIT_UTILS_H */ --- -2.47.3 - diff --git a/0011-docs-nbdkit_timestamp.pod-Fix-copy-and-paste-error-i.patch b/0011-docs-nbdkit_timestamp.pod-Fix-copy-and-paste-error-i.patch new file mode 100644 index 0000000..1129254 --- /dev/null +++ b/0011-docs-nbdkit_timestamp.pod-Fix-copy-and-paste-error-i.patch @@ -0,0 +1,28 @@ +From 90547ea1ee742cf79a46dc0166f5d642df58b480 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 29 Jan 2026 19:27:07 +0000 +Subject: [PATCH] docs/nbdkit_timestamp.pod: Fix copy and paste error in man + page + +Fixes: commit 773d958c8f2a5043053d385b8bfe287c43ee63d4 +(cherry picked from commit 0aea0a18f4665a885b77e1c1461c2aba05a0c604) +--- + docs/nbdkit_timestamp.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/nbdkit_timestamp.pod b/docs/nbdkit_timestamp.pod +index 2662b204..2b6859cf 100644 +--- a/docs/nbdkit_timestamp.pod ++++ b/docs/nbdkit_timestamp.pod +@@ -56,7 +56,7 @@ an error generating the timestamp, the string C<"!"> is returned. + + =head1 HISTORY + +-C was added in nbdkit 1.48. ++C was added in nbdkit 1.48. + + =head1 SEE ALSO + +-- +2.47.3 + diff --git a/0012-todo-Add-item-about-nbdkit_timestamp-on-the-main-thr.patch b/0012-todo-Add-item-about-nbdkit_timestamp-on-the-main-thr.patch new file mode 100644 index 0000000..b94409f --- /dev/null +++ b/0012-todo-Add-item-about-nbdkit_timestamp-on-the-main-thr.patch @@ -0,0 +1,33 @@ +From 996bb5a3acbf4478d4d568ddfdf32aa45fffb633 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 31 Jan 2026 08:41:56 +0000 +Subject: [PATCH] todo: Add item about nbdkit_timestamp on the main thread + +Updates: commit 773d958c8f2a5043053d385b8bfe287c43ee63d4 +(cherry picked from commit e3d6ffc314b9774af31235c3d7ae760f62978861) +--- + TODO.md | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/TODO.md b/TODO.md +index 8488dd95..46e2a0c6 100644 +--- a/TODO.md ++++ b/TODO.md +@@ -87,6 +87,14 @@ + `-4` or `-6` option). Once this mess is fixed, the tests should be + updated to use this. + ++* `nbdkit_timestamp()` does not work when called on the main thread. ++ This is because the main thread does not allocate thread-local ++ storage (see [threadlocal.c](server/threadlocal.c)). We could ++ either special-case this in `nbdkit_timestamp` or we could implement ++ thread-local storage for the main thread (but the latter may change ++ some assumptions in the code). There may be other APIs that are ++ affected in this way too. ++ + ## Suggestions for plugins + + Note: qemu supports other formats such as iscsi and ceph/rbd, and +-- +2.47.3 + diff --git a/0013-server-sockets.c-Print-the-actual-bound-addresses-an.patch b/0013-server-sockets.c-Print-the-actual-bound-addresses-an.patch new file mode 100644 index 0000000..6e4fc70 --- /dev/null +++ b/0013-server-sockets.c-Print-the-actual-bound-addresses-an.patch @@ -0,0 +1,121 @@ +From 02626a83a89068944e8840fef9e6deada9ae67b1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 31 Jan 2026 13:41:36 +0000 +Subject: [PATCH] server/sockets.c: Print the actual bound addresses and ports + in debug output + +Previously when listening on a TCP/IP port, we printed (in debug +output) this: + + nbdkit: debug: bound to IP address :10809 (2 socket(s)) + +Change this to print the actual socket addresses for each socket: + + nbdkit: debug: bound to IPv4 address 0.0.0.0:10809 + nbdkit: debug: bound to IPv6 address [::]:10809 + +We just print the raw IP addresses to avoid doing name lookups. This +is still way harder than it should be. + +(cherry picked from commit 6ef03ffdd451b730ac90d889e758e9151b14db82) +--- + configure.ac | 7 ++++++ + server/sockets.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index a7a021e0..1cc87a44 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -509,6 +509,13 @@ AC_CHECK_MEMBERS([struct sockpeercred.uid], [], [], + #endif + ]]) + ++dnl Check for types. ++AC_CHECK_TYPES([in_port_t], [], [], [[ ++#ifdef HAVE_NETINET_IN_H ++#include ++#endif ++]]) ++ + dnl Replacement functions that we provide for some platforms. + AC_CONFIG_LIBOBJ_DIR([common/replacements]) + AC_REPLACE_FUNCS([\ +diff --git a/server/sockets.c b/server/sockets.c +index 348da029..cef27d57 100644 +--- a/server/sockets.c ++++ b/server/sockets.c +@@ -46,6 +46,10 @@ + #include + #endif + ++#ifdef HAVE_ARPA_INET_H ++#include ++#endif ++ + #ifdef HAVE_SYS_UN_H + #include + #endif +@@ -271,8 +275,57 @@ bind_tcpip_socket (sockets *socks) + exit (EXIT_FAILURE); + } + +- debug ("bound to IP address %s:%s (%zu socket(s))", +- ipaddr ? ipaddr : "", ipport, socks->len); ++ /* Print the IP address of each socket in debug output. */ ++ if (verbose) { ++ char addr_str[128]; ++ size_t i; ++ struct sockaddr_storage ss; ++ socklen_t sslen = sizeof ss; ++ const struct sockaddr_in *sin; ++ const struct sockaddr_in6 *sin6; ++ const void *addr; ++ const char *familyname; ++#ifdef HAVE_IN_PORT_T ++ in_port_t portno; ++#else ++ int portno; ++#endif ++ bool square_brackets = false; ++ ++ for (i = 0; i < socks->len; ++i) { ++ if (getsockname (socks->ptr[i], (struct sockaddr *) &ss, &sslen) == -1) { ++ debug ("getsockname: %m"); ++ continue; ++ } ++ switch (ss.ss_family) { ++ case AF_INET: ++ familyname = "IPv4"; ++ sin = (const struct sockaddr_in *) &ss; ++ addr = &sin->sin_addr; ++ portno = sin->sin_port; ++ break; ++ case AF_INET6: ++ familyname = "IPv6"; ++ square_brackets = true; ++ sin6 = (const struct sockaddr_in6 *) &ss; ++ addr = &sin6->sin6_addr; ++ portno = sin6->sin6_port; ++ break; ++ default: ++ /* Probably can never happen? */ ++ debug ("unknown address family: %d", ss.ss_family); ++ continue; ++ } ++ if (inet_ntop (ss.ss_family, addr, addr_str, sizeof addr_str) == NULL) { ++ debug ("inet_ntop: %m"); ++ continue; ++ } ++ debug ("bound to %s address %s%s%s:%d", ++ familyname, ++ square_brackets ? "[" : "", addr_str, square_brackets ? "]" : "", ++ (int) ntohs (portno)); ++ } ++ } + } + + void +-- +2.47.3 + diff --git a/0014-server-Partially-fix-port-0.patch b/0014-server-Partially-fix-port-0.patch new file mode 100644 index 0000000..91bf156 --- /dev/null +++ b/0014-server-Partially-fix-port-0.patch @@ -0,0 +1,214 @@ +From 410ee57d3708133527769e8b7eeddd5840226cb5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 31 Jan 2026 14:16:30 +0000 +Subject: [PATCH] server: Partially fix --port=0 + +Using nbdkit --port=0 causes nbdkit to open a TCP/IP socket with the +kernel choosing a random port number (usually two port numbers, one +for IPv4 and IPv6). This already worked, mostly, but it didn't update +the port variable and so $port was not set correctly in --run scripts, +making this option useless for our testing. + +Also it didn't, and still does not, set the $uri or the output of +--print-uri correctly. The URI still has ":0" as the port number. +This is more difficult to fix, see my update to the TODO.md file. + +(cherry picked from commit 8251486ec7d899628de246bc3232ddb20dceaa53) +--- + TODO.md | 15 +++++------- + docs/nbdkit.pod | 12 ++++++++++ + server/sockets.c | 47 ++++++++++++++++++++++++++++++++++++++ + tests/Makefile.am | 2 ++ + tests/test-ip-port.sh | 53 +++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 120 insertions(+), 9 deletions(-) + create mode 100755 tests/test-ip-port.sh + +diff --git a/TODO.md b/TODO.md +index 46e2a0c6..af272405 100644 +--- a/TODO.md ++++ b/TODO.md +@@ -77,15 +77,12 @@ + particular `SOL_TCP` + `TCP_KEEPCNT`, `SOL_TCP` + `TCP_KEEPIDLE`, + and `SOL_TCP` + `TCP_KEEPINTVL`. + +-* Fix `--port=0` / allow nbdkit to choose a TCP port: Several tests +- rely on picking a random TCP port, which is racy. The kernel can +- pick a port for us, and nbdkit `--print-uri` function can be used to +- display the random port to the user. Because of a bug, nbdkit lets +- you choose `--port=0`, causing the kernel to pick a port, but +- `--print-uri` doesn't display the port, and a different port is +- picked for IPv4 and IPv6 (so it only makes sense to use this with +- `-4` or `-6` option). Once this mess is fixed, the tests should be +- updated to use this. ++* Using `--port=0` (to get the kernel to pick a random port) works, ++ but the URI in `--print-uri` and `$uri` is wrong. Fixing this is ++ difficult because we generate and print the URI early, long before ++ we bind to ports. There is a case for binding to ports before ++ closing stdio, but that is quite a large change and needs some ++ careful thought. + + * `nbdkit_timestamp()` does not work when called on the main thread. + This is because the main thread does not allocate thread-local +diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod +index 3104d751..ac8a39b3 100644 +--- a/docs/nbdkit.pod ++++ b/docs/nbdkit.pod +@@ -422,6 +422,18 @@ delete the file when it exits. + Change the TCP/IP port number on which nbdkit serves requests. + The default is C<10809>. See also I<-i>. + ++=item B<-p 0> ++ ++=item B<--port=0> ++ ++Setting port to C<0> causes nbdkit to bind to a random free port ++number. On a dual-stack host it will usually bind to a I ++localhost port number for IPv4 and IPv6. ++ ++Currently I<--print-uri> will still print the port as C<":0"> (this is ++a bug), but the true port is available using the C<$port> variable in ++I<--run> scripts. ++ + =item B<--print-uri> + + Print the URI. See L above. +diff --git a/server/sockets.c b/server/sockets.c +index cef27d57..dad7fb3c 100644 +--- a/server/sockets.c ++++ b/server/sockets.c +@@ -326,6 +326,53 @@ bind_tcpip_socket (sockets *socks) + (int) ntohs (portno)); + } + } ++ ++ /* If port == "0" then we let the kernel choose the port number. ++ * (In the normal dual-stack case, it will actually choose two port ++ * numbers, one for IPv4 and one for IPv6). In this case we can ++ * overwrite the port variable with the chosen port number, ++ * preferring IPv6. ++ * ++ * In theory this loop could be combined with the one above but it ++ * makes the code very intricate. ++ */ ++ if (strcmp (port, "0") == 0) { ++ static char port_str[16] = { 0 }; ++ size_t i; ++ struct sockaddr_storage ss; ++ socklen_t sslen = sizeof ss; ++ const struct sockaddr_in *sin; ++ const struct sockaddr_in6 *sin6; ++ ++ for (i = 0; i < socks->len; ++i) { ++ if (getsockname (socks->ptr[i], (struct sockaddr *) &ss, &sslen) == -1) { ++ debug ("getsockname: %m"); ++ continue; ++ } ++ switch (ss.ss_family) { ++ case AF_INET: ++ sin = (const struct sockaddr_in *) &ss; ++ /* For IPv4, don't overwrite if the port_str is already set, ++ * so IPv6 takes priority. ++ */ ++ if (port_str[0] == 0) ++ snprintf (port_str, sizeof port_str, "%d", ++ (int) ntohs (sin->sin_port)); ++ break; ++ case AF_INET6: ++ sin6 = (const struct sockaddr_in6 *) &ss; ++ /* Prefer IPv6, so always override the port_str here. */ ++ snprintf (port_str, sizeof port_str, "%d", ++ (int) ntohs (sin6->sin6_port)); ++ break; ++ default: ++ abort (); ++ } ++ } ++ ++ if (port_str[0] != 0) ++ port = port_str; ++ } + } + + void +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 8b7cb851..e2bc640d 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -302,6 +302,7 @@ TESTS += \ + test-tls-priority.sh \ + test-tls-psk.sh \ + test-not-linked-to-libssl.sh \ ++ test-ip-port.sh \ + test-ipv4-lo.sh \ + test-ipv6-lo.sh \ + test-foreground.sh \ +@@ -379,6 +380,7 @@ EXTRA_DIST += \ + test-foreground.sh \ + test-help-example1.sh \ + test-help-plugin.sh \ ++ test-ip-port.sh \ + test-ipv4-lo.sh \ + test-ipv6-lo.sh \ + test-keepalive.sh \ +diff --git a/tests/test-ip-port.sh b/tests/test-ip-port.sh +new file mode 100755 +index 00000000..cc1aa32e +--- /dev/null ++++ b/tests/test-ip-port.sh +@@ -0,0 +1,53 @@ ++#!/usr/bin/env bash ++# nbdkit ++# Copyright Red Hat ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions are ++# met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in the ++# documentation and/or other materials provided with the distribution. ++# ++# * Neither the name of Red Hat nor the names of its contributors may be ++# used to endorse or promote products derived from this software without ++# specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ++# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR ++# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++# SUCH DAMAGE. ++ ++# Test that --run '$port' has the correct (non-zero) port number when ++# we use --port=0. ++ ++source ./functions.sh ++set -e ++set -x ++set -u ++ ++requires_run ++requires_nbdinfo ++ ++define script <<'EOF' ++echo port = $port ++test "$port" -gt "0" ++ ++# nbdkit does not yet construct $uri correctly when using --port=0 ++# but it does set $port so this will work: ++nbdinfo nbd://localhost:$port ++EOF ++ ++nbdkit -v --port=0 null --run "$script" +-- +2.47.3 + diff --git a/0015-tests-test-ip-filter.sh-Remove-use-of-pick_unused_po.patch b/0015-tests-test-ip-filter.sh-Remove-use-of-pick_unused_po.patch new file mode 100644 index 0000000..42f13af --- /dev/null +++ b/0015-tests-test-ip-filter.sh-Remove-use-of-pick_unused_po.patch @@ -0,0 +1,104 @@ +From 05b8884ccab68a224fe4f240557082fb575bc407 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 31 Jan 2026 14:34:39 +0000 +Subject: [PATCH] tests/test-ip-filter.sh: Remove use of pick_unused_port + +Since nbdkit --port=0 is working somewhat now, we can remove use of +the racy pick_unused_port function. + +We can now improve this test to check IPv6 only filtering. + +(cherry picked from commit 1e1ba9b58a5988af746de0b3c0472e12462b8eb0) +--- + TODO.md | 16 ++++++++++------ + tests/test-ip-filter.sh | 40 ++++++++++++++++++++++++++++++---------- + 2 files changed, 40 insertions(+), 16 deletions(-) + +diff --git a/TODO.md b/TODO.md +index af272405..ecb36f29 100644 +--- a/TODO.md ++++ b/TODO.md +@@ -77,12 +77,16 @@ + particular `SOL_TCP` + `TCP_KEEPCNT`, `SOL_TCP` + `TCP_KEEPIDLE`, + and `SOL_TCP` + `TCP_KEEPINTVL`. + +-* Using `--port=0` (to get the kernel to pick a random port) works, +- but the URI in `--print-uri` and `$uri` is wrong. Fixing this is +- difficult because we generate and print the URI early, long before +- we bind to ports. There is a case for binding to ports before +- closing stdio, but that is quite a large change and needs some +- careful thought. ++* Using `--port=0` (to get the kernel to pick a random port) works: ++ ++ - But the URI in `--print-uri` and `$uri` is wrong. Fixing this is ++ difficult because we generate and print the URI early, long before ++ we bind to ports. There is a case for binding to ports before ++ closing stdio, but that is quite a large change and needs some ++ careful thought. ++ ++ - Consider exposing `$port4` and `$port6` to `--run` scripts. This ++ would allow `tests/test-ip-filter.sh` to work. + + * `nbdkit_timestamp()` does not work when called on the main thread. + This is because the main thread does not allocate thread-local +diff --git a/tests/test-ip-filter.sh b/tests/test-ip-filter.sh +index cb7d6315..c8f7b051 100755 +--- a/tests/test-ip-filter.sh ++++ b/tests/test-ip-filter.sh +@@ -38,7 +38,7 @@ set -e + set -x + set -u + +-requires ip -V ++requires_run + requires_nbdinfo + requires_ipv6_loopback + +@@ -46,15 +46,35 @@ requires_ipv6_loopback + # "nbd://[::1]:$port" URIs (commit 17df436cea5 added in 1.7.7). + requires_libnbd_version 1.8 + +-rm -f ip-filter.pid +-cleanup_fn rm -f ip-filter.pid ++fail=0 + +-# Find an unused port to listen on. +-pick_unused_port ++# Allow IPv4 and IPv6. ++nbdkit -v --port=0 --filter=ip null \ ++ -D ip.rules=1 \ ++ allow=allipv4,allipv6 deny=all \ ++ --run ' ++ nbdinfo "nbd://127.0.0.1:$port" ++ nbdinfo "nbd://[::1]:$port" ++' + +-start_nbdkit -P ip-filter.pid -p $port --filter=ip null \ +- -D ip.rules=1 \ +- allow=allipv4,allipv6 deny=all ++# Allow IPv4 only, deny IPv6. ++# XXX We cannot test this because $port is set preferentially to the ++# IPv6 port, and we cannot find the IPv4 port here. ++#nbdkit -v --port=0 --filter=ip null \ ++# -D ip.rules=1 \ ++# allow=allipv4 deny=all --run 'nbdinfo "nbd://127.0.0.1:$port"' ++# ++#nbdkit -v --port=0 --filter=ip null \ ++# -D ip.rules=1 \ ++# allow=allipv4 deny=all --run 'nbdinfo "nbd://[::1]:$port"' && fail=1 + +-nbdinfo "nbd://127.0.0.1:$port" +-nbdinfo "nbd://[::1]:$port" ++# Allow IPv6 only, deny IPv4. ++nbdkit -v --port=0 --filter=ip null \ ++ -D ip.rules=1 \ ++ allow=allipv6 deny=all --run 'nbdinfo "nbd://[::1]:$port"' ++ ++nbdkit -v --port=0 --filter=ip null \ ++ -D ip.rules=1 \ ++ allow=allipv6 deny=all --run 'nbdinfo "nbd://127.0.0.1:$port"' && fail=1 ++ ++exit $fail +-- +2.47.3 + diff --git a/0016-tests-test-ipv4-lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch b/0016-tests-test-ipv4-lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch new file mode 100644 index 0000000..716f66f --- /dev/null +++ b/0016-tests-test-ipv4-lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch @@ -0,0 +1,109 @@ +From 2cb53b22419fa33f7a85efda0c940116f5c60ea5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 31 Jan 2026 15:31:59 +0000 +Subject: [PATCH] tests/test-ipv4-lo.sh, tests/test-ipv6-lo.sh: Remove + pick_unused_port + +Remove use of pick_unused_port, and greatly simply these tests by +using --run and nbdinfo. + +(cherry picked from commit e1ee17022c63d90dd7469c66ca4980e489fa3f95) +--- + tests/test-ipv4-lo.sh | 35 ++++------------------------------- + tests/test-ipv6-lo.sh | 35 ++++------------------------------- + 2 files changed, 8 insertions(+), 62 deletions(-) + +diff --git a/tests/test-ipv4-lo.sh b/tests/test-ipv4-lo.sh +index e0e1878a..9b6e5c42 100755 +--- a/tests/test-ipv4-lo.sh ++++ b/tests/test-ipv4-lo.sh +@@ -38,36 +38,9 @@ set -e + set -x + set -u + +-# Cannot use kill pidfile below to test if the process is running on +-# Windows. +-if is_windows; then +- echo "$0: this test needs to be revised to work on Windows" +- exit 77 +-fi +- +-requires ip -V +-requires "$QEMU_IMG" --version +-requires "$QEMU_IMG" info --image-opts driver=file,filename=functions.sh +- +-rm -f ipv4lo.pid ipv4lo.out +-cleanup_fn rm -f ipv4lo.pid ipv4lo.out +- +-# Find an unused port to listen on. +-pick_unused_port ++requires_run ++requires_nbdinfo + + # By default nbdkit will listen on all available interfaces, ie. +-# IPv4 and IPv6. +-start_nbdkit -P ipv4lo.pid -p $port example1 +-pid="$(cat ipv4lo.pid)" +- +-# Check the process exists. +-kill -s 0 $pid +- +-# Check we can connect over the IPv4 loopback interface. +-ipv4_lo="$(ip -o -4 addr show scope host)" +-if test -n "$ipv4_lo"; then +- "$QEMU_IMG" info --output=json \ +- --image-opts "file.driver=nbd,file.host=127.0.0.1,file.port=$port" > ipv4lo.out +- cat ipv4lo.out +- grep -sq '"virtual-size": *104857600\b' ipv4lo.out +-fi ++# IPv4 and IPv6, so use -4 to force IPv4 only. ++nbdkit -v -4 --port=0 example1 --run 'nbdinfo nbd://127.0.0.1:$port/' +diff --git a/tests/test-ipv6-lo.sh b/tests/test-ipv6-lo.sh +index d30ae205..ea17bafc 100755 +--- a/tests/test-ipv6-lo.sh ++++ b/tests/test-ipv6-lo.sh +@@ -38,37 +38,10 @@ set -e + set -x + set -u + +-# Cannot use kill pidfile below to test if the process is running on +-# Windows. +-if is_windows; then +- echo "$0: this test needs to be revised to work on Windows" +- exit 77 +-fi +- +-requires ip -V +-requires "$QEMU_IMG" --version +-requires "$QEMU_IMG" info --image-opts driver=file,filename=functions.sh ++requires_run ++requires_nbdinfo + requires_ipv6_loopback + +-rm -f ipv6lo.pid ipv6lo.out +-cleanup_fn rm -f ipv6lo.pid ipv6lo.out +- +-# Find an unused port to listen on. +-pick_unused_port +- + # By default nbdkit will listen on all available interfaces, ie. +-# IPv4 and IPv6. +-start_nbdkit -P ipv6lo.pid -p $port example1 +-pid="$(cat ipv6lo.pid)" +- +-# Check the process exists. +-kill -s 0 $pid +- +-# Check we can connect over the IPv6 loopback interface. +-ipv6_lo="$(ip -o -6 addr show scope host)" +-if test -n "$ipv6_lo"; then +- "$QEMU_IMG" info --output=json \ +- --image-opts "file.driver=nbd,file.host=::1,file.port=$port" > ipv6lo.out +- cat ipv6lo.out +- grep -sq '"virtual-size": *104857600\b' ipv6lo.out +-fi ++# IPv4 and IPv6, so use -6 to force IPv6 only. ++nbdkit -v -6 --port=0 example1 --run 'nbdinfo nbd://[::1]:$port/' +-- +2.47.3 + diff --git a/0017-server-sockets.c-Don-t-crash-if-TCP-IP-selected-with.patch b/0017-server-sockets.c-Don-t-crash-if-TCP-IP-selected-with.patch new file mode 100644 index 0000000..df251ef --- /dev/null +++ b/0017-server-sockets.c-Don-t-crash-if-TCP-IP-selected-with.patch @@ -0,0 +1,51 @@ +From 53f021813744745f0ec0996f4e16bc71d3484336 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 1 Feb 2026 13:40:01 +0000 +Subject: [PATCH] server/sockets.c: Don't crash if TCP/IP selected without + --port + +Because of a thinko in commit 8251486ec7 ("server: Partially fix +--port=0") I neglected the case where we select TCP/IP but don't use +the --port parameter (thus port == NULL), eg: + + $ nbdkit file disk.img + Segmentation fault (core dumped) nbdkit file disk.img + +Ooops. The fix is to use ioport which is never NULL in this function. + +Our tests don't test this case, since we cannot in general open port +10809 safely from the test suite. + +Fixes: commit 8251486ec7d899628de246bc3232ddb20dceaa53 +(cherry picked from commit 490c1a6980de65bb21f007dddb4a5a7ffa136c66) +--- + server/sockets.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/server/sockets.c b/server/sockets.c +index dad7fb3c..473f8ee6 100644 +--- a/server/sockets.c ++++ b/server/sockets.c +@@ -327,8 +327,8 @@ bind_tcpip_socket (sockets *socks) + } + } + +- /* If port == "0" then we let the kernel choose the port number. +- * (In the normal dual-stack case, it will actually choose two port ++ /* If --port=0 then we let the kernel choose the port number. (In ++ * the normal dual-stack case, it will actually choose two port + * numbers, one for IPv4 and one for IPv6). In this case we can + * overwrite the port variable with the chosen port number, + * preferring IPv6. +@@ -336,7 +336,7 @@ bind_tcpip_socket (sockets *socks) + * In theory this loop could be combined with the one above but it + * makes the code very intricate. + */ +- if (strcmp (port, "0") == 0) { ++ if (strcmp (ipport, "0") == 0) { + static char port_str[16] = { 0 }; + size_t i; + struct sockaddr_storage ss; +-- +2.47.3 + diff --git a/0018-sparse-random-Make-block-size-configurable.patch b/0018-sparse-random-Make-block-size-configurable.patch new file mode 100644 index 0000000..b8425db --- /dev/null +++ b/0018-sparse-random-Make-block-size-configurable.patch @@ -0,0 +1,416 @@ +From d48364b33bea7997c38461ba2d85015a8901f2f3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 1 Feb 2026 19:01:54 +0000 +Subject: [PATCH] sparse-random: Make block size configurable + +For trying to reproduce a virt-v2v corruption case, we would like to +use this plugin to simulate quite closely a VDDK source. VDDK uses a +64K block size for extents, which is different from the default (4K) +for this plugin. This change allows us to use 'blocksize=64K' to +simulate this. + +(cherry picked from commit 5612598a49aaf4ac49f1b3e096dc4945ea7df640) +--- + .../nbdkit-sparse-random-plugin.pod | 11 ++- + plugins/sparse-random/sparse-random.c | 99 +++++++++++-------- + tests/Makefile.am | 2 + + tests/test-sparse-random-blocksize.sh | 49 +++++++++ + 4 files changed, 117 insertions(+), 44 deletions(-) + create mode 100755 tests/test-sparse-random-blocksize.sh + +diff --git a/plugins/sparse-random/nbdkit-sparse-random-plugin.pod b/plugins/sparse-random/nbdkit-sparse-random-plugin.pod +index 0d64633f..d0472e00 100644 +--- a/plugins/sparse-random/nbdkit-sparse-random-plugin.pod ++++ b/plugins/sparse-random/nbdkit-sparse-random-plugin.pod +@@ -4,8 +4,8 @@ nbdkit-sparse-random-plugin - make sparse random disks + + =head1 SYNOPSIS + +- nbdkit sparse-random [size=]SIZE [seed=SEED] +- [percent=N] [runlength=N] ++ nbdkit sparse-random [size=]SIZE [blocksize=N] ++ [seed=SEED] [percent=N] [runlength=N] + [random-content=true] + + =head1 DESCRIPTION +@@ -52,6 +52,13 @@ See also L. + + =over 4 + ++=item BN ++ ++Set the block size. This is the granularity that this plugin operates ++at. Sparse extents will be aligned to the block size. ++ ++It must be a power of 2 and E 1024. The default is 4096. ++ + =item BN + + Specify the approximate percentage of the disk which contains random +diff --git a/plugins/sparse-random/sparse-random.c b/plugins/sparse-random/sparse-random.c +index 823f85a1..8d1c2944 100644 +--- a/plugins/sparse-random/sparse-random.c ++++ b/plugins/sparse-random/sparse-random.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -46,6 +47,7 @@ + #include "bitmap.h" + #include "cleanup.h" + #include "isaligned.h" ++#include "ispowerof2.h" + #include "iszero.h" + #include "minmax.h" + #include "random.h" +@@ -60,7 +62,7 @@ static int random_content; /* false: Repeat same byte true: Random bytes*/ + /* We need to store 1 bit per block. Using a 4K block size means we + * need 32M to map each 1T of virtual disk. + */ +-#define BLOCKSIZE 4096 ++static unsigned blocksize = 4096; + + static struct bitmap bm; /* Bitmap of data blocks. */ + +@@ -72,8 +74,6 @@ sparse_random_load (void) + * parameter. + */ + seed = time (NULL); +- +- bitmap_init (&bm, BLOCKSIZE, 1 /* bits per block */); + } + + static void +@@ -97,6 +97,18 @@ sparse_random_config (const char *key, const char *value) + return -1; + size = r; + } ++ else if (strcmp (key, "blocksize") == 0 || ++ strcmp (key, "block-size") == 0) { ++ r = nbdkit_parse_size (value); ++ if (r == -1) ++ return -1; ++ if (r < 1024 || r > 0x10000000 || !is_power_of_2 (r)) { ++ nbdkit_error ("block size must be a power of 2, " ++ "and between 1024 and 2^28"); ++ return -1; ++ } ++ blocksize = r; ++ } + else if (strcmp (key, "percent") == 0) { + if (sscanf (value, "%lf", &percent) != 1 || + percent < 0 || percent > 100) { +@@ -129,6 +141,7 @@ sparse_random_config (const char *key, const char *value) + + #define sparse_random_config_help \ + "size= (required) Size of the backing disk\n" \ ++ "blocksize= Set block size (default: 4K)\n" \ + "seed= Random number generator seed\n" \ + "percent= Percentage of data\n" \ + "runlength= Expected average run length of data\n" \ +@@ -182,6 +195,8 @@ sparse_random_get_ready (void) + uint64_t data_run_length = 0; + uint64_t avg_data_run_length = 0; + ++ bitmap_init (&bm, blocksize, 1 /* bits per block */); ++ + if (bitmap_resize (&bm, size) == -1) + return -1; + +@@ -196,7 +211,7 @@ sparse_random_get_ready (void) + } + + /* Otherwise calculate the probability parameters as above. */ +- P_dh = 1. / ((double) runlength / BLOCKSIZE); ++ P_dh = 1. / ((double) runlength / blocksize); + P_hd = (percent / 100.) * P_dh / (1. - (percent / 100.)); + + nbdkit_debug ("percent requested = %g%%, " +@@ -242,8 +257,8 @@ sparse_random_get_ready (void) + avg_data_run_length = 0; + nbdkit_debug ("percent actual = %g%%, " + "average run length = %" PRIu64, +- 100. * BLOCKSIZE * nr_data_blocks / size, +- avg_data_run_length * BLOCKSIZE); ++ 100. * blocksize * nr_data_blocks / size, ++ avg_data_run_length * blocksize); + + return 0; + } +@@ -270,7 +285,7 @@ sparse_random_block_size (void *handle, + uint32_t *maximum) + { + *minimum = 1; +- *preferred = BLOCKSIZE; ++ *preferred = blocksize; + *maximum = 0xffffffff; + return 0; + } +@@ -301,20 +316,20 @@ read_block (uint64_t blknum, uint64_t offset, void *buf) + struct random_state state; + + if (bitmap_get_blk (&bm, blknum, 0) == 0) /* hole */ +- memset (buf, 0, BLOCKSIZE); ++ memset (buf, 0, blocksize); + else if (!random_content) { /* data when random-content=false */ + xsrandom (seed + offset, &state); + s = xrandom (&state); + s &= 255; + if (s == 0) s = 1; +- memset (buf, (int)s, BLOCKSIZE); ++ memset (buf, (int)s, blocksize); + } + else { /* data when random-content=true */ + /* This produces repeatable data for the same offset. Note it + * works because we are called on whole blocks only. + */ + xsrandom (seed + offset, &state); +- for (i = 0; i < BLOCKSIZE; ++i) { ++ for (i = 0; i < blocksize; ++i) { + s = xrandom (&state); + s &= 255; + b[i] = s; +@@ -330,20 +345,20 @@ sparse_random_pread (void *handle, void *buf, uint32_t count, uint64_t offset, + CLEANUP_FREE uint8_t *block = NULL; + uint64_t blknum, blkoffs; + +- if (!IS_ALIGNED (count | offset, BLOCKSIZE)) { +- block = malloc (BLOCKSIZE); ++ if (!IS_ALIGNED (count | offset, blocksize)) { ++ block = malloc (blocksize); + if (block == NULL) { + nbdkit_error ("malloc: %m"); + return -1; + } + } + +- blknum = offset / BLOCKSIZE; /* block number */ +- blkoffs = offset % BLOCKSIZE; /* offset within the block */ ++ blknum = offset / blocksize; /* block number */ ++ blkoffs = offset % blocksize; /* offset within the block */ + + /* Unaligned head */ + if (blkoffs) { +- uint64_t n = MIN (BLOCKSIZE - blkoffs, count); ++ uint64_t n = MIN (blocksize - blkoffs, count); + + read_block (blknum, offset, block); + memcpy (buf, &block[blkoffs], n); +@@ -355,12 +370,12 @@ sparse_random_pread (void *handle, void *buf, uint32_t count, uint64_t offset, + } + + /* Aligned body */ +- while (count >= BLOCKSIZE) { ++ while (count >= blocksize) { + read_block (blknum, offset, buf); + +- buf += BLOCKSIZE; +- count -= BLOCKSIZE; +- offset += BLOCKSIZE; ++ buf += blocksize; ++ count -= blocksize; ++ offset += blocksize; + blknum++; + } + +@@ -386,18 +401,18 @@ sparse_random_pwrite (void *handle, const void *buf, + CLEANUP_FREE uint8_t *block; + uint64_t blknum, blkoffs; + +- block = malloc (BLOCKSIZE); ++ block = malloc (blocksize); + if (block == NULL) { + nbdkit_error ("malloc: %m"); + return -1; + } + +- blknum = offset / BLOCKSIZE; /* block number */ +- blkoffs = offset % BLOCKSIZE; /* offset within the block */ ++ blknum = offset / blocksize; /* block number */ ++ blkoffs = offset % blocksize; /* offset within the block */ + + /* Unaligned head */ + if (blkoffs) { +- uint64_t n = MIN (BLOCKSIZE - blkoffs, count); ++ uint64_t n = MIN (blocksize - blkoffs, count); + + read_block (blknum, offset, block); + if (memcmp (buf, &block[blkoffs], n) != 0) { +@@ -414,23 +429,23 @@ sparse_random_pwrite (void *handle, const void *buf, + } + + /* Aligned body */ +- while (count >= BLOCKSIZE) { ++ while (count >= blocksize) { + /* As an optimization, skip calling read_block if we know this is + * a hole. Call is_zero instead which should be faster. + */ + if (bitmap_get_blk (&bm, blknum, 0) == 0) { +- if (! is_zero (buf, BLOCKSIZE)) ++ if (! is_zero (buf, blocksize)) + goto unexpected_data; + } + else { + read_block (blknum, offset, block); +- if (memcmp (buf, block, BLOCKSIZE) != 0) ++ if (memcmp (buf, block, blocksize) != 0) + goto unexpected_data; + } + +- buf += BLOCKSIZE; +- count -= BLOCKSIZE; +- offset += BLOCKSIZE; ++ buf += blocksize; ++ count -= blocksize; ++ offset += blocksize; + blknum++; + } + +@@ -465,12 +480,12 @@ sparse_random_trim_zero (void *handle, uint32_t count, uint64_t offset, + { + uint64_t blknum, blkoffs; + +- blknum = offset / BLOCKSIZE; /* block number */ +- blkoffs = offset % BLOCKSIZE; /* offset within the block */ ++ blknum = offset / blocksize; /* block number */ ++ blkoffs = offset % blocksize; /* offset within the block */ + + /* Unaligned head */ + if (blkoffs) { +- uint64_t n = MIN (BLOCKSIZE - blkoffs, count); ++ uint64_t n = MIN (blocksize - blkoffs, count); + + if (bitmap_get_blk (&bm, blknum, 0) != 0) { + unexpected_trim: +@@ -485,12 +500,12 @@ sparse_random_trim_zero (void *handle, uint32_t count, uint64_t offset, + } + + /* Aligned body */ +- while (count >= BLOCKSIZE) { ++ while (count >= blocksize) { + if (bitmap_get_blk (&bm, blknum, 0) != 0) + goto unexpected_trim; + +- count -= BLOCKSIZE; +- offset += BLOCKSIZE; ++ count -= blocksize; ++ offset += blocksize; + blknum++; + } + +@@ -510,12 +525,12 @@ sparse_random_extents (void *handle, uint32_t count, uint64_t offset, + uint64_t blknum, blkoffs; + uint32_t type; + +- blknum = offset / BLOCKSIZE; /* block number */ +- blkoffs = offset % BLOCKSIZE; /* offset within the block */ ++ blknum = offset / blocksize; /* block number */ ++ blkoffs = offset % blocksize; /* offset within the block */ + + /* Unaligned head */ + if (blkoffs) { +- uint64_t n = MIN (BLOCKSIZE - blkoffs, count); ++ uint64_t n = MIN (blocksize - blkoffs, count); + + if (bitmap_get_blk (&bm, blknum, 0) == 0) + type = NBDKIT_EXTENT_HOLE | NBDKIT_EXTENT_ZERO; +@@ -530,16 +545,16 @@ sparse_random_extents (void *handle, uint32_t count, uint64_t offset, + } + + /* Aligned body */ +- while (count >= BLOCKSIZE) { ++ while (count >= blocksize) { + if (bitmap_get_blk (&bm, blknum, 0) == 0) + type = NBDKIT_EXTENT_HOLE | NBDKIT_EXTENT_ZERO; + else + type = 0; /* data */ +- if (nbdkit_add_extent (extents, offset, BLOCKSIZE, type) == -1) ++ if (nbdkit_add_extent (extents, offset, blocksize, type) == -1) + return -1; + +- count -= BLOCKSIZE; +- offset += BLOCKSIZE; ++ count -= blocksize; ++ offset += blocksize; + blknum++; + } + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index e2bc640d..2ae0c3c2 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1293,10 +1293,12 @@ EXTRA_DIST += \ + + # sparse-random plugin test. + TESTS += \ ++ test-sparse-random-blocksize.sh \ + test-sparse-random-copy.sh \ + test-sparse-random-info.sh \ + $(NULL) + EXTRA_DIST += \ ++ test-sparse-random-blocksize.sh \ + test-sparse-random-copy.sh \ + test-sparse-random-info.sh \ + $(NULL) +diff --git a/tests/test-sparse-random-blocksize.sh b/tests/test-sparse-random-blocksize.sh +new file mode 100755 +index 00000000..c1230809 +--- /dev/null ++++ b/tests/test-sparse-random-blocksize.sh +@@ -0,0 +1,49 @@ ++#!/usr/bin/env bash ++# nbdkit ++# Copyright Red Hat ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions are ++# met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in the ++# documentation and/or other materials provided with the distribution. ++# ++# * Neither the name of Red Hat nor the names of its contributors may be ++# used to endorse or promote products derived from this software without ++# specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ++# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR ++# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++# SUCH DAMAGE. ++ ++# Test the sparse-random plugin with non-standard blocksize. ++ ++source ./functions.sh ++set -e ++set -x ++set -u ++ ++requires_run ++ ++# nbdcopy >= 1.5.9 required for this test. ++requires_nbdcopy ++requires_libnbd_version 1.5.9 ++ ++nbdkit -v \ ++ sparse-random \ ++ size=10G blocksize=64K \ ++ --run 'nbdcopy "$uri" "$uri"' +-- +2.47.3 + diff --git a/0019-sparse-random-Clamp-preferred-block-size.patch b/0019-sparse-random-Clamp-preferred-block-size.patch new file mode 100644 index 0000000..1adde8f --- /dev/null +++ b/0019-sparse-random-Clamp-preferred-block-size.patch @@ -0,0 +1,39 @@ +From bf567e9488c0241cd58c13ef998b208a7f8a58f3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 1 Feb 2026 21:21:59 +0000 +Subject: [PATCH] sparse-random: Clamp preferred block size + +The preferred block size must be between 512 and 32M. It was possible +to set a larger block size, so we must clamp it. (I clamped it at +both ends, even though currently the smallest block size is 1024). + +Fixes: commit 5612598a49aaf4ac49f1b3e096dc4945ea7df640 +(cherry picked from commit 7a7a103b0711a89a1912d6768db4a91bec3a5f17) +--- + plugins/sparse-random/sparse-random.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/plugins/sparse-random/sparse-random.c b/plugins/sparse-random/sparse-random.c +index 8d1c2944..3d7da426 100644 +--- a/plugins/sparse-random/sparse-random.c ++++ b/plugins/sparse-random/sparse-random.c +@@ -285,7 +285,15 @@ sparse_random_block_size (void *handle, + uint32_t *maximum) + { + *minimum = 1; +- *preferred = blocksize; ++ ++ /* Preferred blocksize must be 512..32M so clamp this value. */ ++ if (blocksize < 512) ++ *preferred = 512; ++ else if (blocksize > 32*1024*1024) ++ *preferred = 32*1024*1024; ++ else ++ *preferred = blocksize; ++ + *maximum = 0xffffffff; + return 0; + } +-- +2.47.3 + diff --git a/0020-tests-test-sparse-random-blocksize.sh-Enhance-the-te.patch b/0020-tests-test-sparse-random-blocksize.sh-Enhance-the-te.patch new file mode 100644 index 0000000..a35c7cd --- /dev/null +++ b/0020-tests-test-sparse-random-blocksize.sh-Enhance-the-te.patch @@ -0,0 +1,60 @@ +From 26dd53f15d522ae137ec92afa2f49fd010ff2c15 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 1 Feb 2026 21:09:04 +0000 +Subject: [PATCH] tests/test-sparse-random-blocksize.sh: Enhance the test + +Check that all extents are aligned to the block size, and randomly +select the block size so we are testing both small and large blocks. + +Updates: commit 5612598a49aaf4ac49f1b3e096dc4945ea7df640 +(cherry picked from commit e11011043556b6ee4333212264bdefa5324eedc4) +--- + tests/test-sparse-random-blocksize.sh | 28 +++++++++++++++++++++++++-- + 1 file changed, 26 insertions(+), 2 deletions(-) + +diff --git a/tests/test-sparse-random-blocksize.sh b/tests/test-sparse-random-blocksize.sh +index c1230809..3ddc1f26 100755 +--- a/tests/test-sparse-random-blocksize.sh ++++ b/tests/test-sparse-random-blocksize.sh +@@ -38,12 +38,36 @@ set -x + set -u + + requires_run ++requires_nbdinfo + + # nbdcopy >= 1.5.9 required for this test. + requires_nbdcopy + requires_libnbd_version 1.5.9 + ++out=sparse-random-blocksize.out ++cleanup_fn rm -f $out ++rm -f $out ++ ++#blocksize=65536 ++blocksize_r="$(( 10 + (RANDOM % 19) ))" ;# 10..28 ++blocksize="$(( 1 << blocksize_r ))" ++ ++export out + nbdkit -v \ + sparse-random \ +- size=10G blocksize=64K \ +- --run 'nbdcopy "$uri" "$uri"' ++ size=10G blocksize=$blocksize \ ++ --run ' ++ nbdinfo --map "$uri" > $out && ++ nbdcopy "$uri" "$uri" ++' ++ ++# Check all the extents are aligned to $blocksize ++cat $out ++( while read offset size rest ; do ++ echo checking $offset $size ... ++ if test "$(( $offset % blocksize ))" != 0 || ++ test "$(( $size % blocksize ))" != 0 ; then ++ echo error: extent is not aligned to $blocksize: offset $offset size $size ++ exit 1 ++ fi ++done ) <$out +-- +2.47.3 + diff --git a/0021-tests-test-sparse-random-blocksize.sh-Reduce-maximum.patch b/0021-tests-test-sparse-random-blocksize.sh-Reduce-maximum.patch new file mode 100644 index 0000000..b755eee --- /dev/null +++ b/0021-tests-test-sparse-random-blocksize.sh-Reduce-maximum.patch @@ -0,0 +1,40 @@ +From 2e4212b86bd56ff6aaec6166cc3198050fcb172a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 8 Feb 2026 22:10:17 +0000 +Subject: [PATCH] tests/test-sparse-random-blocksize.sh: Reduce maximum block + size + +On i686 this would fail if blocksize=32M was chosen, because we could +allocate (up to) 4 connections * 16 threads * 32M == 2G of RAM. +Probably we are not allocating that much, but it still often failed +with blocksize=32M. + +Reduce the maximum we will choose down to 8M. + +(cherry picked from commit 5edcc592dc9d4466596618da2d7507b575492a02) +--- + tests/test-sparse-random-blocksize.sh | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tests/test-sparse-random-blocksize.sh b/tests/test-sparse-random-blocksize.sh +index 3ddc1f26..29eec3f8 100755 +--- a/tests/test-sparse-random-blocksize.sh ++++ b/tests/test-sparse-random-blocksize.sh +@@ -49,7 +49,13 @@ cleanup_fn rm -f $out + rm -f $out + + #blocksize=65536 +-blocksize_r="$(( 10 + (RANDOM % 19) ))" ;# 10..28 ++ ++# We could do this: ++#blocksize_r="$(( 10 + (RANDOM % 19) ))" ;# 10..28 ++# but if this picks a 32M block size, then this could consume up to ++# 4 * 16 * 32 == 2048 MB of RAM. This is a problem on smaller systems ++# (and especially 32 bit), so choose a lesser maximum. ++blocksize_r="$(( 10 + (RANDOM % 17) ))" ;# 10..26 + blocksize="$(( 1 << blocksize_r ))" + + export out +-- +2.47.3 + diff --git a/nbdkit.spec b/nbdkit.spec index b6a82fb..cc6e7b9 100644 --- a/nbdkit.spec +++ b/nbdkit.spec @@ -54,8 +54,8 @@ %global source_directory 1.46-stable Name: nbdkit -Version: 1.46.1 -Release: 3%{?dist} +Version: 1.46.2 +Release: 1%{?dist} Summary: NBD server License: BSD-3-Clause @@ -80,23 +80,27 @@ Source3: copy-patches.sh # https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-10.2/ # Patches. -Patch0001: 0001-python-Link-to-C-man-pages-for-module-functions.patch -Patch0002: 0002-python-Sort-documentation-for-module-functions-in-or.patch -Patch0003: 0003-blocksize-policy-Fix-assertion-failure-on-unaligned-.patch -Patch0004: 0004-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch -Patch0005: 0005-todo-Add-note-about-problems-with-file-plugin-block_.patch -Patch0006: 0006-file-Change-calculations-of-block-size-hints-for-blo.patch -Patch0007: 0007-qcow2dec-Don-t-pass-flags-from-.extents-through-to-..patch -Patch0008: 0008-vddk-Test-with-VDDK-9.0.1.0.patch -Patch0009: 0009-configure.ac-Remove-use-of-which-command.patch -Patch0010: 0010-map-Fix-documentation-about-changing-the-size-of-the.patch -Patch0011: 0011-common-utils-utils.h-Add-C-boilerplate.patch -Patch0012: 0012-server-Add-nbdkit_debug_hexdiff-function.patch -Patch0013: 0013-checkwrite-Display-differences-if-D-checkwrite.showd.patch -Patch0014: 0014-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch -Patch0015: 0015-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch -Patch0016: 0016-Add-new-nbdkit_name-function.patch -Patch0017: 0017-server-test-public.c-Add-process_name-dummy-variable.patch +Patch0001: 0001-vram-Cast-cl_ulong-to-uint64_t-before-printing.patch +Patch0002: 0002-server-Add-nbdkit_debug_hexdiff-function.patch +Patch0003: 0003-checkwrite-Display-differences-if-D-checkwrite.showd.patch +Patch0004: 0004-docs-nbdkit_debug_hexdump.pod-Document-when-hexdiff-.patch +Patch0005: 0005-docs-nbdkit_debug_hexdump.pod-Add-a-link-back-to-nbd.patch +Patch0006: 0006-Add-new-nbdkit_name-function.patch +Patch0007: 0007-server-test-public.c-Add-process_name-dummy-variable.patch +Patch0008: 0008-Add-new-nbdkit_timestamp-function.patch +Patch0009: 0009-log-Use-nbdkit_timestamp.patch +Patch0010: 0010-docs-nbdkit-plugin.pod-Add-a-link-to-nbdkit_timestam.patch +Patch0011: 0011-docs-nbdkit_timestamp.pod-Fix-copy-and-paste-error-i.patch +Patch0012: 0012-todo-Add-item-about-nbdkit_timestamp-on-the-main-thr.patch +Patch0013: 0013-server-sockets.c-Print-the-actual-bound-addresses-an.patch +Patch0014: 0014-server-Partially-fix-port-0.patch +Patch0015: 0015-tests-test-ip-filter.sh-Remove-use-of-pick_unused_po.patch +Patch0016: 0016-tests-test-ipv4-lo.sh-tests-test-ipv6-lo.sh-Remove-p.patch +Patch0017: 0017-server-sockets.c-Don-t-crash-if-TCP-IP-selected-with.patch +Patch0018: 0018-sparse-random-Make-block-size-configurable.patch +Patch0019: 0019-sparse-random-Clamp-preferred-block-size.patch +Patch0020: 0020-tests-test-sparse-random-blocksize.sh-Enhance-the-te.patch +Patch0021: 0021-tests-test-sparse-random-blocksize.sh-Reduce-maximum.patch # For automatic RPM Provides generation. # See: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html @@ -1604,9 +1608,10 @@ fi %changelog -* Tue Jan 20 2026 Richard W.M. Jones - 1.46.1-3 -- Rebase to nbdkit 1.46.1 -- Backport nbdkit_debug_hexdiff and nbdkit_name from nbdkit 1.47. +* Mon Feb 09 2026 Richard W.M. Jones - 1.46.2-1 +- Rebase to nbdkit 1.46.2 +- Backport nbdkit_debug_hexdiff, nbdkit_name, nbdkit_timestamp + from nbdkit 1.47. resolves: RHEL-111242 - Synchronize spec file with Fedora. - vddk: Don't use FNM_PATHNAME when matching export parameter diff --git a/sources b/sources index 279ae3d..fd8126b 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (nbdkit-1.46.1.tar.gz) = 7a4223e4b22314dd711cfa09e24d248b02a084ffef35b4cd4df83f9c9e5c485abc1cd2dfc609be82ef2c35841259035b3a388dd0b779bf17d20318132da69747 -SHA512 (nbdkit-1.46.1.tar.gz.sig) = 53140ec57584b7f2946f193036fedd1ea232f6364f75716c11dfb6d6d9941a7a28d82a51d959ae1b7a075b36604c013182c10a9cab7f6ee3b58cba937b150e4c +SHA512 (nbdkit-1.46.2.tar.gz) = ce01ac7a90cb995ec3ef46c8cec0be7b47d7266edc4383df6e867881fd4ba66b5f36ccc4de356a0df0f1d47f86adb40212e8de62332d19014b293649f25d4b37 +SHA512 (nbdkit-1.46.2.tar.gz.sig) = 73df3e276564c292ef5d94e6f5db0e25c77c65d1f6dab4d090528e7546340cfbea5e96bb385841ac4c2de29eebf7e52db8e74fbf3b59bbb48cef64e50dfa0790