diff --git a/0001-file-Change-windows_fd_lock-into-reader-writer-lock.patch b/0001-file-Change-windows_fd_lock-into-reader-writer-lock.patch new file mode 100644 index 0000000..192650c --- /dev/null +++ b/0001-file-Change-windows_fd_lock-into-reader-writer-lock.patch @@ -0,0 +1,52 @@ +From 5197cb20661565176fcec5ce231cf165abd97152 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 18 Dec 2025 21:09:11 +0000 +Subject: [PATCH] file: Change windows_fd_lock into reader/writer lock + +Previous commit 01efc4410f ("file: Don't allow oldest.fd to be closed +during evict_writes") mistakenly used a regular lock to protect +oldest.fd. This kind of lock _is_ contended, serializing writes which +we didn't want. + +Instead use a reader/writer lock. The writes use the reader lock so +are not contended. Only when we want to close the file descriptor do +we need to take an exclusive (ie. writer) lock. + +Fixes: commit 01efc4410f3d3f20cf5d5059a6a6423b48dc864e +Fixes: commit d3d2bc45bb59a30669a3d926435cf57e99feb3a2 +--- + plugins/file/file.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/plugins/file/file.c b/plugins/file/file.c +index 7de5183a..6a8e65c9 100644 +--- a/plugins/file/file.c ++++ b/plugins/file/file.c +@@ -118,13 +118,13 @@ struct write_window { + }; + + static pthread_mutex_t window_lock = PTHREAD_MUTEX_INITIALIZER; +-static pthread_mutex_t window_fd_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_rwlock_t window_fd_lock = PTHREAD_RWLOCK_INITIALIZER; + static struct write_window window[NR_WINDOWS]; + + static int + evict_writes (int fd, uint64_t offset, size_t len) + { +- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_fd_lock); ++ ACQUIRE_RDLOCK_FOR_CURRENT_SCOPE (&window_fd_lock); + struct write_window oldest = { 0 }; + + { +@@ -184,7 +184,7 @@ evict_writes (int fd, uint64_t offset, size_t len) + static void + remove_fd_from_window (int fd) + { +- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_fd_lock); ++ ACQUIRE_WRLOCK_FOR_CURRENT_SCOPE (&window_fd_lock); + size_t i; + + for (i = 0; i < NR_WINDOWS; ++i) +-- +2.47.3 + diff --git a/0001-vram-Skip-listing-devices-when-no-platforms-are-foun.patch b/0001-vram-Skip-listing-devices-when-no-platforms-are-foun.patch deleted file mode 100644 index 8301565..0000000 --- a/0001-vram-Skip-listing-devices-when-no-platforms-are-foun.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cad6894ec6dc18b318d0948fadf5833ecd75cb0f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 26 Oct 2025 22:25:10 +0000 -Subject: [PATCH] vram: Skip listing devices when no platforms are found - -In a chroot-type test environment, tests/test-dump-plugin.sh failed -with: - - + nbdkit vram --dump-plugin - nbdkit: error: clGetPlatformIDs: error -1001 (unknown OpenCL error) - --1001 is the extended error CL_PLATFORM_NOT_FOUND_KHR ---- - plugins/vram/opencl-errors.h | 3 +++ - plugins/vram/vram.c | 7 +++++++ - 2 files changed, 10 insertions(+) - -diff --git a/plugins/vram/opencl-errors.h b/plugins/vram/opencl-errors.h -index b5d185fc..dd6fba92 100644 ---- a/plugins/vram/opencl-errors.h -+++ b/plugins/vram/opencl-errors.h -@@ -101,6 +101,9 @@ opencl_errstr (cl_int err) - case_return_string(CL_INVALID_COMPILER_OPTIONS ); - case_return_string(CL_INVALID_LINKER_OPTIONS ); - case_return_string(CL_INVALID_DEVICE_PARTITION_COUNT ); -+ -+ /* Extended. */ -+ case_return_string(CL_PLATFORM_NOT_FOUND_KHR ); - default: return "unknown OpenCL error"; - } - } -diff --git a/plugins/vram/vram.c b/plugins/vram/vram.c -index 4b391e22..9819f0db 100644 ---- a/plugins/vram/vram.c -+++ b/plugins/vram/vram.c -@@ -41,6 +41,7 @@ - - #define CL_TARGET_OPENCL_VERSION 200 /* OpenCL >= 2.0 */ - #include -+#include - - #define NBDKIT_API_VERSION 2 - #include -@@ -126,6 +127,12 @@ get_all_devices (void) - /* Build the list of all devices from all platforms as a flat list. */ - what = "clGetPlatformIDs"; - r = clGetPlatformIDs (0, NULL, &num_platforms); -+ if (r == CL_PLATFORM_NOT_FOUND_KHR) { -+ /* OpenCL seems to return this when no platform is detected at -+ * all, so just return the empty list in this case. -+ */ -+ return; -+ } - if (r != CL_SUCCESS) goto err; - platform_ids = calloc (num_platforms, sizeof platform_ids[0]); - if (!platform_ids) { --- -2.47.3 - diff --git a/0002-linuxdisk-Fix-parsing-of-last-line-of-du-command-out.patch b/0002-linuxdisk-Fix-parsing-of-last-line-of-du-command-out.patch deleted file mode 100644 index a85c54f..0000000 --- a/0002-linuxdisk-Fix-parsing-of-last-line-of-du-command-out.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 01b8e557ce129b2f4677061ba04bbb5ff2a703eb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 27 Oct 2025 09:15:47 +0000 -Subject: [PATCH] linuxdisk: Fix parsing of last line of 'du' command output - -A recent change to glibc breaks this code. Previously we could read -the lines of output from the 'du' command until getline(3) returned -EOF, and the 'line' buffer would contain the last line read. However -after this change, glibc now sets line[0] = '\0' in the EOF case, -breaking the last line of output that we wanted to parse. - -https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=33eff78c8b28adc4963987880e10d96761f2a167 - -We also previously didn't handle the unlikely case where 'du' produces -no output at all. Fix both problems here. ---- - plugins/linuxdisk/filesystem.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - -diff --git a/plugins/linuxdisk/filesystem.c b/plugins/linuxdisk/filesystem.c -index 3e4e2f3a..283af61a 100644 ---- a/plugins/linuxdisk/filesystem.c -+++ b/plugins/linuxdisk/filesystem.c -@@ -148,7 +148,7 @@ create_filesystem (struct virtual_disk *disk) - static int64_t - estimate_size (void) - { -- CLEANUP_FREE char *command = NULL, *line = NULL; -+ CLEANUP_FREE char *command = NULL, *line = NULL, *lastline = NULL; - size_t len = 0; - FILE *fp; - int64_t ret; -@@ -177,8 +177,16 @@ estimate_size (void) - - /* Ignore everything up to the last line. */ - len = 0; -- while (getline (&line, &len, fp) != -1) -- /* empty */; -+ while (getline (&line, &len, fp) != -1) { -+ nbdkit_debug ("du: %s", line); -+ free (lastline); -+ lastline = strndup (line, len); -+ if (lastline == NULL) { -+ nbdkit_error ("strndup: %m"); -+ pclose (fp); -+ return -1; -+ } -+ } - if (ferror (fp)) { - nbdkit_error ("getline failed: %m"); - pclose (fp); -@@ -193,9 +201,14 @@ estimate_size (void) - if (exit_status_to_nbd_error (r, "pclose: du") == -1) - return -1; - -+ if (lastline == NULL) { -+ nbdkit_error ("no output from du command"); -+ return -1; -+ } -+ - /* Parse the last line. */ -- if (sscanf (line, "%" SCNi64, &ret) != 1 || ret < 0) { -- nbdkit_error ("could not parse last line of output: %s", line); -+ if (sscanf (lastline, "%" SCNi64, &ret) != 1 || ret < 0) { -+ nbdkit_error ("could not parse last line from du command: %s", lastline); - return -1; - } - --- -2.47.3 - diff --git a/0002-server-Add-nbdkit_debug_hexdump-function.patch b/0002-server-Add-nbdkit_debug_hexdump-function.patch new file mode 100644 index 0000000..bf4f5ef --- /dev/null +++ b/0002-server-Add-nbdkit_debug_hexdump-function.patch @@ -0,0 +1,576 @@ +From 6f5579c88a30b322cc604f65580f088b1e738d1c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 19 Dec 2025 13:41:43 +0000 +Subject: [PATCH] server: Add nbdkit_debug_hexdump function + +This emits a buffer to debug output in the same format as 'hexdump -C'. +--- + .gitignore | 1 + + docs/Makefile.am | 7 ++ + docs/nbdkit-plugin.pod | 1 + + docs/nbdkit_debug.pod | 1 + + docs/nbdkit_debug_hexdump.pod | 54 +++++++++++ + include/nbdkit-common.h | 3 + + server/debug.c | 72 ++++++++++++++ + server/nbdkit.syms | 1 + + tests/Makefile.am | 26 +++++ + tests/test-debug-hexdump-plugin.c | 85 +++++++++++++++++ + tests/test-debug-hexdump.sh | 154 ++++++++++++++++++++++++++++++ + 11 files changed, 405 insertions(+) + create mode 100644 docs/nbdkit_debug_hexdump.pod + create mode 100755 tests/test-debug-hexdump-plugin.c + create mode 100755 tests/test-debug-hexdump.sh + +diff --git a/.gitignore b/.gitignore +index ecb76feb..3562a665 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -28,6 +28,7 @@ __pycache__ + + docs/*.1 + docs/nbdkit_debug.3 ++docs/nbdkit_debug_hexdump.3 + docs/nbdkit_error.3 + docs/nbdkit_export_name.3 + docs/nbdkit-filter.3 +diff --git a/docs/Makefile.am b/docs/Makefile.am +index 9e3a4d75..240d9e1d 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -38,6 +38,7 @@ EXTRA_DIST = \ + nbdkit-captive.pod \ + nbdkit-client.pod \ + nbdkit_debug.pod \ ++ nbdkit_debug_hexdump.pod \ + nbdkit_error.pod \ + nbdkit_export_name.pod \ + nbdkit-filter.pod \ +@@ -126,6 +127,7 @@ generated_mans = \ + nbdkit-captive.1 \ + nbdkit-client.1 \ + nbdkit_debug.3 \ ++ nbdkit_debug_hexdump.3 \ + nbdkit_error.3 \ + nbdkit_export_name.3 \ + nbdkit-filter.3 \ +@@ -206,6 +208,11 @@ nbdkit_debug.3: nbdkit_debug.pod $(top_builddir)/podwrapper.pl + --html $(top_builddir)/html/$@.html \ + $< + ++nbdkit_debug_hexdump.3: nbdkit_debug_hexdump.pod $(top_builddir)/podwrapper.pl ++ $(PODWRAPPER) --section=3 --man $@ \ ++ --html $(top_builddir)/html/$@.html \ ++ $< ++ + nbdkit_error.3: nbdkit_error.pod $(top_builddir)/podwrapper.pl + $(PODWRAPPER) --section=3 --man $@ \ + --html $(top_builddir)/html/$@.html \ +diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod +index 6310fff1..61deb63b 100644 +--- a/docs/nbdkit-plugin.pod ++++ b/docs/nbdkit-plugin.pod +@@ -1624,6 +1624,7 @@ Utility functions provided by nbdkit for plugins and filters to use: + + L, + L, ++L, + L, + L, + L, +diff --git a/docs/nbdkit_debug.pod b/docs/nbdkit_debug.pod +index 638f2726..43bb5a41 100644 +--- a/docs/nbdkit_debug.pod ++++ b/docs/nbdkit_debug.pod +@@ -57,6 +57,7 @@ C was present in nbdkit 0.1.0. + =head1 SEE ALSO + + L, ++L, + L, + L, + L. +diff --git a/docs/nbdkit_debug_hexdump.pod b/docs/nbdkit_debug_hexdump.pod +new file mode 100644 +index 00000000..c48e8eae +--- /dev/null ++++ b/docs/nbdkit_debug_hexdump.pod +@@ -0,0 +1,54 @@ ++=head1 NAME ++ ++nbdkit_debug_hexdump - display buffer in hexdump format ++ ++=head1 SYNOPSIS ++ ++ #include ++ ++ void nbdkit_debug_hexdump (const void *buf, size_t len, ++ const char *prefix, uint64_t start); ++ ++=head1 DESCRIPTION ++ ++This function displays a buffer of binary data in canonical hexdump ++format, sending the output to the same place as L. ++For example: ++ ++ char buf[33] = "12345678123456781234567812345678"; ++ nbdkit_debug_hexdump (buf, 32, "data: ", 0); ++ ++would produce output similar to this: ++ ++ data: 00000000: 31 32 33 34 35 36 37 38 31 32 33 34 35 36 37 38 |1234567812345678| ++ data: 00000010: 31 32 33 34 35 36 37 38 31 32 33 34 35 36 37 38 |1234567812345678| ++ ++An optional C may be given which prefixes the string on each ++line of output. (This may be C or C<""> for no prefix). ++ ++An optional C may be given which changes the first offset ++displayed in the output. ++ ++=head1 LANGUAGE BINDINGS ++ ++(There are no language bindings of this function in the current version.) ++ ++=head1 HISTORY ++ ++C was added in nbdkit 1.46. ++ ++=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 bb5e3e55..eeb60b8b 100644 +--- a/include/nbdkit-common.h ++++ b/include/nbdkit-common.h +@@ -104,6 +104,9 @@ NBDKIT_EXTERN_DECL (void, nbdkit_vdebug, + ATTRIBUTE_FORMAT_PRINTF (1, 0)); + + NBDKIT_EXTERN_DECL (char *, nbdkit_absolute_path, (const char *path)); ++NBDKIT_EXTERN_DECL (void, nbdkit_debug_hexdump, ++ (const void *buf, size_t len, ++ const char *prefix, uint64_t start)); + NBDKIT_EXTERN_DECL (int64_t, nbdkit_parse_size, (const char *str)); + NBDKIT_EXTERN_DECL (int, nbdkit_parse_probability, + (const char *what, const char *str, double *r)); +diff --git a/server/debug.c b/server/debug.c +index fb13af6a..bd9b4ddb 100644 +--- a/server/debug.c ++++ b/server/debug.c +@@ -35,13 +35,18 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include + + #include "ansi-colours.h" ++#include "ascii-ctype.h" ++#include "isaligned.h" + #include "open_memstream.h" ++#include "rounding.h" + #include "utils.h" + + #include "internal.h" +@@ -166,3 +171,70 @@ debug_in_server (const char *fs, ...) + + errno = err; + } ++ ++/* Usually this function would be part of server/public.c, but in this ++ * case we want to use nbdkit_debug instead of debug_in_server. ++ */ ++NBDKIT_DLL_PUBLIC void ++nbdkit_debug_hexdump (const void *vbuf, size_t len, ++ const char *prefix, uint64_t start) ++{ ++ const uint8_t *buf = vbuf; ++ uint64_t offset = start, skip; ++ size_t i; ++ char str_offset[16+1]; /* The offset field */ ++ char hex[16*3+1]; /* Sixteen pairs of hex digits (or spaces) */ ++ char chars[16+1]; /* The printable chars (or spaces) */ ++ ++#define HEXDUMP_RESET_STRS() \ ++ snprintf (str_offset, sizeof str_offset, "%08" PRIx64, \ ++ ROUND_DOWN (offset, 16)); \ ++ memset (hex, ' ', sizeof hex); \ ++ hex[sizeof hex - 1] = '\0'; \ ++ memset (chars, ' ', sizeof chars - 1); \ ++ chars[sizeof chars - 1] = '\0'; ++ ++#define HEXDUMP_SET_BYTE(i, b) \ ++ sprintf (&hex[(i)*3], "%02x", (b)); \ ++ hex[(i)*3+2] = ' '; \ ++ chars[i] = ascii_isprint ((b)) ? (b) : '.'; ++ ++/* Send the final string to nbdkit_debug. Start by splitting up the ++ * hex digits into two groups of 8. ++ */ ++#define HEXDUMP_EMIT_DEBUG() \ ++ hex[8*3-1] = '\0'; \ ++ nbdkit_debug ("%s%s: %s %s |%s|", \ ++ prefix ? : "", \ ++ str_offset, hex, &hex[8*3], chars); ++ ++ /* Unaligned head. */ ++ if (! IS_ALIGNED (offset, 16)) { ++ HEXDUMP_RESET_STRS (); ++ skip = offset % 16; ++ for (i = skip; i < 16 && len > 0; ++i) { ++ HEXDUMP_SET_BYTE (i, *buf); ++ buf++; ++ offset++; ++ len--; ++ } ++ HEXDUMP_EMIT_DEBUG (); ++ } ++ ++ /* Aligned body and unaligned tail. */ ++ while (len > 0) { ++ assert (IS_ALIGNED (offset, 16)); ++ HEXDUMP_RESET_STRS (); ++ for (i = 0; i < 16 && len > 0; ++i) { ++ HEXDUMP_SET_BYTE (i, *buf); ++ buf++; ++ offset++; ++ len--; ++ } ++ HEXDUMP_EMIT_DEBUG (); ++ } ++ ++#undef HEXDUMP_RESET_STRS ++#undef HEXDUMP_SET_BYTE ++#undef HEXDUMP_EMIT_DEBUG ++} +diff --git a/server/nbdkit.syms b/server/nbdkit.syms +index 1393f1ea..239e6db1 100644 +--- a/server/nbdkit.syms ++++ b/server/nbdkit.syms +@@ -44,6 +44,7 @@ + nbdkit_context_get_backend; + nbdkit_context_set_next; + nbdkit_debug; ++ nbdkit_debug_hexdump; + nbdkit_disconnect; + nbdkit_error; + nbdkit_export_name; +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 75183b92..759a5237 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -327,6 +327,7 @@ TESTS += \ + test-log-to-file.sh \ + test-log-to-file-append.sh \ + test-at-file.sh \ ++ test-debug-hexdump.sh \ + $(NULL) + if !IS_WINDOWS + TESTS += \ +@@ -358,6 +359,8 @@ EXTRA_DIST += \ + test-export-handshake.sh \ + test-export-handshake-tls.sh \ + test-debug-flags.sh \ ++ test-debug-hexdump.sh \ ++ test-debug-hexdump-plugin.c \ + test-disconnect-tls.sh \ + test-disconnect.sh \ + test-dump-plugin-and-single.sh \ +@@ -531,6 +534,29 @@ test_shutdown_plugin_la_LDFLAGS = \ + $(NULL) + test_shutdown_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-debug-hexdump-plugin.la \ ++ $(NULL) ++test-debug-hexdump.sh: test-debug-hexdump-plugin.la ++ ++test_debug_hexdump_plugin_la_SOURCES = \ ++ test-debug-hexdump-plugin.c \ ++ $(top_srcdir)/include/nbdkit-plugin.h \ ++ $(NULL) ++test_debug_hexdump_plugin_la_CPPFLAGS = \ ++ -I$(top_srcdir)/include \ ++ -I$(top_builddir)/include \ ++ $(NULL) ++test_debug_hexdump_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) ++# For use of the -rpath option, see: ++# https://lists.gnu.org/archive/html/libtool/2007-07/msg00067.html ++test_debug_hexdump_plugin_la_LDFLAGS = \ ++ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ ++ $(NULL) ++test_debug_hexdump_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-debug-hexdump-plugin.c b/tests/test-debug-hexdump-plugin.c +new file mode 100755 +index 00000000..138edb04 +--- /dev/null ++++ b/tests/test-debug-hexdump-plugin.c +@@ -0,0 +1,85 @@ ++/* 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. ++ */ ++ ++/* Plugin for testing nbdkit_debug_hexdump. See nbdkit-debug-hexdump.sh */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#define NBDKIT_API_VERSION 2 ++#include ++ ++static void * ++password_open (int readonly) ++{ ++ return NBDKIT_HANDLE_NOT_NEEDED; ++} ++ ++static int64_t ++password_get_size (void *handle) ++{ ++ return INT64_MAX; ++} ++ ++#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS ++ ++/* Never actually called, but return zeroes. */ ++static int ++password_pread (void *handle, void *buf, uint32_t count, uint64_t offset, ++ uint32_t flags) ++{ ++ memset (buf, 0, count); ++ return 0; ++} ++ ++/* We hexdump the buffer, with a prefix string, and discard the data. */ ++static int ++password_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, ++ uint32_t flags) ++{ ++ nbdkit_debug_hexdump (buf, count, "DUMP: ", offset); ++ return 0; ++} ++ ++static struct nbdkit_plugin plugin = { ++ .name = "hexdump-debug", ++ .version = PACKAGE_VERSION, ++ .open = password_open, ++ .get_size = password_get_size, ++ .pread = password_pread, ++ .pwrite = password_pwrite, ++}; ++ ++NBDKIT_REGISTER_PLUGIN (plugin) +diff --git a/tests/test-debug-hexdump.sh b/tests/test-debug-hexdump.sh +new file mode 100755 +index 00000000..85b8429c +--- /dev/null ++++ b/tests/test-debug-hexdump.sh +@@ -0,0 +1,154 @@ ++#!/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 nbdkit_debug_hexdump function. ++ ++source ./functions.sh ++set -e ++set -x ++set -u ++ ++requires_run ++requires_nbdsh_uri ++requires diff --version ++requires $SED --version ++ ++plugin=.libs/test-debug-hexdump-plugin.$SOEXT ++requires test -f $plugin ++ ++out=debug-shutdown.out ++hexout=debug-shutdown.hexout ++files="$out $hexout" ++rm -f $files ++cleanup_fn rm -f $files ++ ++define script <<'EOF' ++import os ++ ++offset = int(os.getenv("offset"), 0) ++count = int(os.getenv("count"), 0) ++ ++data = os.getenv("data") ++b = bytearray(data, encoding='utf8') ++if len(b) < count: ++ b += bytearray(count - len(b)) ++assert(len(b) == count) ++ ++h.pwrite(b, offset) ++EOF ++export script ++ ++do_test () ++{ ++ count="$1" ++ offset="$2" ++ data="$3" ++ export offset count data ++ ++ # Run nbdkit with the plugin and debug enabled. Capture the full ++ # output including stderr so we can find the hexdump output. ++ fail= ++ nbdkit -f -v $plugin --run 'nbdsh -u "$uri" -c "$script"' \ ++ >$out 2>&1 || fail=1 ++ cat $out ++ if test "$fail"; then exit 1; fi ++ ++ # Get the hexdump lines from the output. ++ grep "DUMP: " < $out | $SED 's/.*DUMP: //' > $hexout ++ cat $hexout ++ ++ # Compare it to the expected output (in $expected variable). ++ diff -u $hexout <(echo -n "$expected") ++} ++ ++define expected <<'EOF' ++00000000: 31 |1 | ++EOF ++do_test 1 0 '1' ++ ++define expected <<'EOF' ++00000000: 31 | 1 | ++EOF ++do_test 1 1 '1' ++ ++define expected <<'EOF' ++00000000: 31 32 33 | 123 | ++EOF ++do_test 3 1 '123' ++ ++define expected <<'EOF' ++00000000: 31 32 33 00 00 00 00 00 00 00 00 00 00 00 00 | 123............| ++00000010: 00 |. | ++EOF ++do_test 16 1 '123' ++ ++define expected <<'EOF' ++00000000: 31 32 33 61 62 63 01 00 00 00 00 00 00 00 00 00 |123abc..........| ++EOF ++do_test 16 0 $'123abc\x01' ++ ++define expected <<'EOF' ++00000000: 31 32 33 00 00 00 00 00 00 00 00 00 00 00 00 00 |123.............| ++00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ++EOF ++do_test 32 0 '123' ++ ++define expected <<'EOF' ++00000010: 31 32 33 00 00 00 00 00 00 00 00 00 00 00 00 00 |123.............| ++EOF ++do_test 16 16 '123' ++ ++define expected <<'EOF' ++00000000: 31 32 33 00 00 00 00 00 | 123.....| ++00000010: 00 00 00 00 00 00 00 00 |........ | ++EOF ++do_test 16 8 '123' ++ ++define expected <<'EOF' ++00000000: 31 32 33 00 00 00 00 00 00 00 | 123.......| ++00000010: 00 00 00 00 00 00 00 00 |........ | ++EOF ++do_test 18 6 '123' ++ ++define expected <<'EOF' ++ffff00000000: 31 32 33 00 00 00 00 00 00 00 | 123.......| ++ffff00000010: 00 00 00 00 00 00 00 00 |........ | ++EOF ++do_test 18 0xffff00000006 '123' ++ ++# XXX In future we might make hexdump choose the longest format for ++# the offset field across all lines of output. ++define expected <<'EOF' ++fffffffffff0: 31 32 33 00 00 00 00 00 00 00 | 123.......| ++1000000000000: 00 00 00 00 00 00 00 00 |........ | ++EOF ++do_test 18 0xfffffffffff6 '123' +-- +2.47.3 + diff --git a/0003-vram-Skip-listing-devices-when-no-devices-found-in-p.patch b/0003-vram-Skip-listing-devices-when-no-devices-found-in-p.patch deleted file mode 100644 index 6932c8d..0000000 --- a/0003-vram-Skip-listing-devices-when-no-devices-found-in-p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From df5e7d1b6f2cbc3e3adbb85312490b148ad0b2fc Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Sun, 26 Oct 2025 22:25:10 +0000 -Subject: [PATCH] vram: Skip listing devices when no devices found in platform - -On my laptop, right after installing clinfo and building vram, -clGetDeviceIDs found an AMD device, but was unable to connect to it -(probably further drivers needed), resulting in: - - + nbdkit vram --dump-plugin - ... - nbdkit: error: clGetDeviceIDs: error -1 (CL_DEVICE_NOT_FOUND) - -Similar to the previous fix when a platform is not available, it is -easy to gracefully handle no devices found in a platform. - -Signed-off-by: Eric Blake ---- - plugins/vram/vram.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/plugins/vram/vram.c b/plugins/vram/vram.c -index 9819f0db..64cfe0fa 100644 ---- a/plugins/vram/vram.c -+++ b/plugins/vram/vram.c -@@ -147,6 +147,13 @@ get_all_devices (void) - what = "clGetDeviceIDs"; - r = clGetDeviceIDs (platform_ids[pl_i], CL_DEVICE_TYPE_ALL, 0, NULL, - &num_devices); -+ if (r == CL_DEVICE_NOT_FOUND) { -+ /* OpenCL seems to return this when the platform is found but -+ * the vendor's library is not configured to access devices -+ * within the platform; skip over this platform. -+ */ -+ continue; -+ } - if (r != CL_SUCCESS) goto err; - free (device_ids); - device_ids = calloc (num_devices, sizeof device_ids[0]); --- -2.47.3 - diff --git a/0004-Fix-mke2fs-command-line.patch b/0004-Fix-mke2fs-command-line.patch deleted file mode 100644 index 82ecd5f..0000000 --- a/0004-Fix-mke2fs-command-line.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ae9a7cf9167bc35aa7278f55af1049ea4aa871e6 Mon Sep 17 00:00:00 2001 -From: Mykola Ivanets -Date: Wed, 29 Oct 2025 23:53:03 +0200 -Subject: [PATCH] Fix mke2fs command line - -Man page says: - -The file system size is specified by fs-size. If fs-size does not have -a suffix, it is interpreted as power-of-two kilobytes, unless the -b -blocksize option is specified, in which case fs-size is interpreted as -the number of blocksize blocks. If the fs-size is suffixed by 'k', 'm', -'g', 't' (either upper-case or lower-case), then it is interpreted in -power-of-two kilobytes, megabytes, gigabytes, terabytes, etc. If -fs-size is omitted, mke2fs will create the file system based on the -device size. - -We could add '-b 1' parameter and specify fs-size, or just remove -fs-size parameter, in this case mke2fs will create the file system based - on device size. I prefer later option just because it will avoid - duplicating fs-size specification twice (in the previous 'truncate' - command and in 'mke2fs'). ---- - tests/Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 53cc00d1..2a7e9623 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -1895,7 +1895,7 @@ ext2.img: disk test-ext2-exportname.sh - cp $< ext2.img.d/disks/disk.img - echo /disks/disk.img > ext2.img.d/manifest - $(TRUNCATE) -s 2147483648 $@-t -- mke2fs -q -F -t ext4 -d ext2.img.d $@-t 2147483648 -+ mke2fs -q -F -t ext4 -d ext2.img.d $@-t - rm -r ext2.img.d - mv $@-t $@ - --- -2.47.3 - diff --git a/0005-vram-Fix-trim-command.patch b/0005-vram-Fix-trim-command.patch deleted file mode 100644 index 4a13fae..0000000 --- a/0005-vram-Fix-trim-command.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 258822bde3eb4923b309431c6e4d71932e83932d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 1 Nov 2025 09:33:37 +0000 -Subject: [PATCH] vram: Fix trim command - -Fix missing updates in the loop, which caused trim operations to spin -forever. - -Fixes: commit e35fb68748ecd1ebab63308db3c9a6ccca12ebcb ---- - plugins/vram/vram.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/plugins/vram/vram.c b/plugins/vram/vram.c -index 64cfe0fa..63e7d5c7 100644 ---- a/plugins/vram/vram.c -+++ b/plugins/vram/vram.c -@@ -811,6 +811,10 @@ vram_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags) - /* Aligned body */ - while (count >= BUFFER_SIZE) { - free_buffer (bufnum); -+ -+ count -= BUFFER_SIZE; -+ offset += BUFFER_SIZE; -+ bufnum++; - } - - return 0; --- -2.47.3 - diff --git a/0006-vram-Link-to-radeontop-1.patch b/0006-vram-Link-to-radeontop-1.patch deleted file mode 100644 index f6dbfcc..0000000 --- a/0006-vram-Link-to-radeontop-1.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1c501d5c7162ac41e6e49767cdcb8632d5e6535d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 1 Nov 2025 09:34:47 +0000 -Subject: [PATCH] vram: Link to radeontop(1) - -This tool is a top-like tool for AMD Radeon cards, very useful when -observing GPU and Video RAM usage in real time. ---- - plugins/vram/nbdkit-vram-plugin.pod | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/plugins/vram/nbdkit-vram-plugin.pod b/plugins/vram/nbdkit-vram-plugin.pod -index b99eb67f..5363a4ca 100644 ---- a/plugins/vram/nbdkit-vram-plugin.pod -+++ b/plugins/vram/nbdkit-vram-plugin.pod -@@ -158,6 +158,7 @@ L, - L, - L, - L, -+L, - L. - - =head1 AUTHORS --- -2.47.3 - diff --git a/0007-vram-Obey-trim-FUA-flag-by-calling-vram_flush.patch b/0007-vram-Obey-trim-FUA-flag-by-calling-vram_flush.patch deleted file mode 100644 index 2b84f4b..0000000 --- a/0007-vram-Obey-trim-FUA-flag-by-calling-vram_flush.patch +++ /dev/null @@ -1,29 +0,0 @@ -From af18957aa91b61f627c2a56724b717c2dbdbf001 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 1 Nov 2025 19:05:01 +0000 -Subject: [PATCH] vram: Obey trim FUA flag by calling vram_flush - -Further fix to the vram trim operation, so now we (kind of) obey the -FUA flag by calling vram_flush. Since vram_flush does nothing right -now, this actually makes no difference. ---- - plugins/vram/vram.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/plugins/vram/vram.c b/plugins/vram/vram.c -index 63e7d5c7..fe8bf60e 100644 ---- a/plugins/vram/vram.c -+++ b/plugins/vram/vram.c -@@ -817,6 +817,9 @@ vram_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags) - bufnum++; - } - -+ if (flags & NBDKIT_FLAG_FUA && vram_flush (handle, 0) == -1) -+ return -1; -+ - return 0; - } - --- -2.47.3 - diff --git a/nbdkit.spec b/nbdkit.spec index f3f55b9..0d9abfe 100644 --- a/nbdkit.spec +++ b/nbdkit.spec @@ -54,7 +54,7 @@ %global source_directory 1.45-development Name: nbdkit -Version: 1.45.12 +Version: 1.45.17 Release: 1%{?dist} Summary: NBD server @@ -80,13 +80,8 @@ Source3: copy-patches.sh # https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-10.2/ # Patches. -Patch0001: 0001-vram-Skip-listing-devices-when-no-platforms-are-foun.patch -Patch0002: 0002-linuxdisk-Fix-parsing-of-last-line-of-du-command-out.patch -Patch0003: 0003-vram-Skip-listing-devices-when-no-devices-found-in-p.patch -Patch0004: 0004-Fix-mke2fs-command-line.patch -Patch0005: 0005-vram-Fix-trim-command.patch -Patch0006: 0006-vram-Link-to-radeontop-1.patch -Patch0007: 0007-vram-Obey-trim-FUA-flag-by-calling-vram_flush.patch +Patch0001: 0001-file-Change-windows_fd_lock-into-reader-writer-lock.patch +Patch0002: 0002-server-Add-nbdkit_debug_hexdump-function.patch # For automatic RPM Provides generation. # See: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html @@ -1516,7 +1511,7 @@ fi %files devel -%doc BENCHMARKING OTHER_PLUGINS README.md SECURITY TODO +%doc BENCHMARKING OTHER_PLUGINS README.md SECURITY.md TODO.md %license LICENSE # Include the source of the example plugins in the documentation. %doc plugins/example*/*.c @@ -1594,8 +1589,8 @@ fi %changelog -* Wed Nov 05 2025 Richard W.M. Jones - 1.45.12-1 -- Rebase to nbdkit 1.45.12 +* Fri Dec 19 2025 Richard W.M. Jones - 1.45.17-1 +- Rebase to nbdkit 1.45.17 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 5539189..a6e9f90 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (nbdkit-1.45.12.tar.gz) = a28da3e24c333da5b4b22961078095b1d73bb6c219e7cfae783c301b68d8e755ce839fa15bff6354b44ff7227a91eae6a8e264f3e26b5caff8d27c68905ff01b -SHA512 (nbdkit-1.45.12.tar.gz.sig) = 93c497160f196b1a6144819742cee04b1fad663a148dbc4fd82efe73c9a1aabdcb9c01baa9ec84db17a392ae6cde468736750a878bba3e3c130507890f96a8e5 +SHA512 (nbdkit-1.45.17.tar.gz) = 7d3fa31ee47b569ec1fee260921bdd5db1da327610c4ea5a2c3bd7450765084cdcdbc40d628c06b287b13ab21e76f7057a0e75055000282e51423529c440813a +SHA512 (nbdkit-1.45.17.tar.gz.sig) = ce24e28481bb436371e6b51330cb72d96e895200ae49b8e2b0536791b7bbcf928fbd781481dd9eedac0c659f3f3a0c6dbece3e6599f8e6a3eae49c30a00e1146