diff --git a/.gitignore b/.gitignore index a2da4ec..f41aad6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/libguestfs.keyring -SOURCES/nbdkit-1.40.4.tar.gz +libguestfs.keyring +nbdkit-1.44.1.tar.gz diff --git a/.nbdkit.metadata b/.nbdkit.metadata deleted file mode 100644 index cf9ec77..0000000 --- a/.nbdkit.metadata +++ /dev/null @@ -1,2 +0,0 @@ -cc1b37b9cfafa515aab3eefd345ecc59aac2ce7b SOURCES/libguestfs.keyring -b2efd184db679430aa17e70f69077fff4df7f7dd SOURCES/nbdkit-1.40.4.tar.gz diff --git a/0001-common-Add-ONCE-macro-to-run-code-only-once.patch b/0001-common-Add-ONCE-macro-to-run-code-only-once.patch new file mode 100644 index 0000000..6452a5f --- /dev/null +++ b/0001-common-Add-ONCE-macro-to-run-code-only-once.patch @@ -0,0 +1,272 @@ +From de37da4184c55c6811dd02707fdd3b1773a7ce66 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 4 Jul 2025 08:13:48 +0100 +Subject: [PATCH] common: Add ONCE macro to run code only once + +This macro can be used to run code once, especially for debug messages +and similar. eg: + + /* Print this once in the log. */ + ONCE (nbdkit_debug ("falling back to less efficient method")); + +(cherry picked from commit ad8630deab4639e636212f11a5a47d2c34ef2949) +--- + .gitignore | 1 + + common/include/Makefile.am | 6 ++ + common/include/once.h | 67 ++++++++++++++++++++ + common/include/test-once.c | 126 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 200 insertions(+) + create mode 100644 common/include/once.h + create mode 100644 common/include/test-once.c + +diff --git a/.gitignore b/.gitignore +index 3629ef39..827fd53c 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -68,6 +68,7 @@ plugins/*/*.3 + /common/include/test-iszero + /common/include/test-minmax + /common/include/test-nextnonzero ++/common/include/test-once + /common/include/test-random + /common/include/test-tvdiff + /common/protocol/generate-protostrings.sh +diff --git a/common/include/Makefile.am b/common/include/Makefile.am +index ca488e68..3a3757e2 100644 +--- a/common/include/Makefile.am ++++ b/common/include/Makefile.am +@@ -49,6 +49,7 @@ EXTRA_DIST = \ + iszero.h \ + minmax.h \ + nextnonzero.h \ ++ once.h \ + random.h \ + rounding.h \ + static-assert.h \ +@@ -71,6 +72,7 @@ TESTS = \ + test-iszero \ + test-minmax \ + test-nextnonzero \ ++ test-once \ + test-random \ + test-tvdiff \ + $(NULL) +@@ -120,6 +122,10 @@ test_nextnonzero_SOURCES = test-nextnonzero.c nextnonzero.h + test_nextnonzero_CPPFLAGS = -I$(srcdir) + test_nextnonzero_CFLAGS = $(WARNINGS_CFLAGS) + ++test_once_SOURCES = test-once.c once.h ++test_once_CPPFLAGS = -I$(srcdir) ++test_once_CFLAGS = $(WARNINGS_CFLAGS) ++ + test_random_SOURCES = test-random.c random.h + test_random_CPPFLAGS = -I$(srcdir) + test_random_CFLAGS = $(WARNINGS_CFLAGS) +diff --git a/common/include/once.h b/common/include/once.h +new file mode 100644 +index 00000000..bb93e767 +--- /dev/null ++++ b/common/include/once.h +@@ -0,0 +1,67 @@ ++/* 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. ++ */ ++ ++#ifndef NBDKIT_ONCE_H ++#define NBDKIT_ONCE_H ++ ++#ifdef HAVE_STDATOMIC_H ++#include ++#else ++/* This is best effort on platforms that don't support atomic. ++ * 32 bit ints are generally fine in reality. ++ */ ++#define _Atomic /**/ ++#endif ++ ++#include "unique-name.h" ++ ++/* Run the statement once (per nbdkit run). */ ++#define ONCE(stmt) ONCE_1(NBDKIT_UNIQUE_NAME(_once), (stmt)) ++ ++/* The actual implementation: ++ * ++ * The comparison with 0 avoids var wrapping around. Mostly var will ++ * only be 0 or 1, or in rare cases other small integers. ++ * ++ * The atomic increment & comparison with 1 is what only allows a ++ * single thread to run the statement. ++ * ++ * To avoid optimisations: Use 'volatile' so reads and writes are not ++ * removed, and use 'unsigned' to avoid any with signed overflow. ++ */ ++#define ONCE_1(var, stmt) \ ++ do { \ ++ static volatile _Atomic unsigned var = 0; \ ++ if (var == 0 && ++var == 1) { stmt; } \ ++ } while (0) ++ ++#endif /* NBDKIT_ONCE_H */ +diff --git a/common/include/test-once.c b/common/include/test-once.c +new file mode 100644 +index 00000000..d7dd5c42 +--- /dev/null ++++ b/common/include/test-once.c +@@ -0,0 +1,126 @@ ++/* 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. ++ */ ++ ++#include ++ ++#include ++#include ++ ++#ifndef HAVE_STDATOMIC_H ++ ++/* Skip the test if no */ ++ ++int ++main (void) ++{ ++ printf ("SKIP: no on this platform\n"); ++ exit (77); ++} ++ ++#else /* HAVE_STDATOMIC_H */ ++ ++#include ++#include ++#include ++ ++#undef NDEBUG /* Keep test strong even for nbdkit built without assertions */ ++#include ++ ++#include ++ ++#include "once.h" ++ ++#define NR_THREADS 8 ++ ++static volatile _Atomic unsigned count1 = 0, count2 = 0, ++ count3 = 0, count4 = 0; ++static pthread_barrier_t barrier; ++ ++static void * __attribute__((noreturn)) ++start_thread (void *idxp) ++{ ++ //int idx = * (int*) idxp; ++ ++ pthread_barrier_wait (&barrier); ++ ++ for (;;) { ++ ONCE (count1++); ++ ONCE (count2++); ++ ONCE (count3++); ++ ONCE (count4++); ++ } ++} ++ ++int ++main (void) ++{ ++ int i, err; ++ pthread_t th[NR_THREADS]; ++ int idx[NR_THREADS]; ++ ++ err = pthread_barrier_init (&barrier, NULL, NR_THREADS); ++ if (err != 0) { ++ errno = err; ++ perror ("pthread_barrier_init"); ++ exit (EXIT_FAILURE); ++ } ++ ++ for (i = 0; i < NR_THREADS; ++i) { ++ idx[i] = i; ++ err = pthread_create (&th[i], NULL, start_thread, &idx[i]); ++ if (err != 0) { ++ errno = err; ++ perror ("pthread_create"); ++ exit (EXIT_FAILURE); ++ } ++ } ++ ++ do { ++ sleep (1); ++ } while (count1 + count2 + count3 + count4 < 4); ++ ++ for (i = 0; i < NR_THREADS; ++i) { ++ pthread_cancel (th[i]); ++ } ++ ++ pthread_barrier_destroy (&barrier); ++ ++ if (count1 != 1 || count2 != 1 || count3 != 1 || count4 != 1) { ++ fprintf (stderr, "FAIL: counts incremented to %u %u %u %u " ++ "(expected 1 1 1 1)\n", count1, count2, count3, count4); ++ exit (EXIT_FAILURE); ++ } ++ ++ exit (EXIT_SUCCESS); ++} ++ ++#endif /* HAVE_STDATOMIC_H */ +-- +2.47.3 + diff --git a/0002-file-zero-Print-the-debug-message-on-the-fallback-pa.patch b/0002-file-zero-Print-the-debug-message-on-the-fallback-pa.patch new file mode 100644 index 0000000..9316256 --- /dev/null +++ b/0002-file-zero-Print-the-debug-message-on-the-fallback-pa.patch @@ -0,0 +1,38 @@ +From 56dba3f1fe87f119e05b74787197ec776ef2692d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 4 Jul 2025 08:20:43 +0100 +Subject: [PATCH] file: zero: Print the debug message on the fallback path once + +Use the new ONCE() macro to print the debug message when we fall back +to emulating zero only once. (Actually the core server code contains +a similar message so we probably don't need this at all.) + +(cherry picked from commit fbb5d8211bf4c30144d01be80720e1a63ecd6e81) +--- + plugins/file/file.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/plugins/file/file.c b/plugins/file/file.c +index 9c43ff24..b881da37 100644 +--- a/plugins/file/file.c ++++ b/plugins/file/file.c +@@ -71,6 +71,7 @@ + #include "isaligned.h" + #include "ispowerof2.h" + #include "minmax.h" ++#include "once.h" + #include "utils.h" + + static enum { +@@ -1165,7 +1166,7 @@ file_zero (void *handle, uint32_t count, uint64_t offset, uint32_t flags) + + /* Trigger a fall back to writing */ + if (file_debug_zero) +- nbdkit_debug ("zero falling back to writing"); ++ ONCE (nbdkit_debug ("%s: zero falling back to writing", h->name)); + errno = EOPNOTSUPP; + return -1; + +-- +2.47.3 + diff --git a/0003-file-trim-Don-t-try-BLKDISCARD-if-earlier-FALLOC_FL_.patch b/0003-file-trim-Don-t-try-BLKDISCARD-if-earlier-FALLOC_FL_.patch new file mode 100644 index 0000000..8b3137d --- /dev/null +++ b/0003-file-trim-Don-t-try-BLKDISCARD-if-earlier-FALLOC_FL_.patch @@ -0,0 +1,65 @@ +From c9132973f88015586aa847ffcaa96e86bb23776f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 4 Jul 2025 08:14:55 +0100 +Subject: [PATCH] file: trim: Don't try BLKDISCARD if earlier + FALLOC_FL_PUNCH_HOLE worked + +In file_zero, we test if the operations we are trying succeed and if +so jump to a single 'out:' label where we deal with the success path +out of that function. + +We did not do the same thing in file_trim. Thus in the case where +FALLOC_FL_PUNCH_HOLE succeeds, we might fall through to trying +BLKDISCARD as well. As it happens we probably don't do this (at +least, in Linux) because we only try BLKDISCARD for block devices, and +FALLOC_FL_PUNCH_HOLE does not work on those. But it's a good thing to +clean up this code anyway, especially if we were to add more cases in +future. + +This also adds a debug message if none of the trim methods worked, +which is also analogous to what happens in the same part of file_zero. + +(cherry picked from commit 909e483c121c69e6b2759ef9d5401eb3d5acc998) +--- + plugins/file/file.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/plugins/file/file.c b/plugins/file/file.c +index b881da37..66d03d4f 100644 +--- a/plugins/file/file.c ++++ b/plugins/file/file.c +@@ -1191,6 +1191,7 @@ file_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags) + + r = do_fallocate (h->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + offset, count); ++ if (r == 0) goto out; + if (r == -1) { + if (!is_enotsup (errno)) { + nbdkit_error ("fallocate: %s: offset=%" PRIu64 ", count=%" PRIu32 ":" +@@ -1214,6 +1215,7 @@ file_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags) + uint64_t range[2] = {offset, count}; + + r = ioctl (h->fd, BLKDISCARD, &range); ++ if (r == 0) goto out; + if (r == -1) { + if (!is_enotsup (errno)) { + nbdkit_error ("ioctl: %s: offset=%" PRIu64 ", count=%" PRIu32 ":" +@@ -1227,6 +1229,15 @@ file_trim (void *handle, uint32_t count, uint64_t offset, uint32_t flags) + } + #endif + ++ /* Trim is advisory. If we got here, we were unable to trim. */ ++ ONCE (nbdkit_debug ("%s: could not trim, no trim methods worked", ++ h->name)); ++ return 0; ++ ++#ifdef __clang__ ++ __attribute__ ((unused)) ++#endif ++ out: + if ((flags & NBDKIT_FLAG_FUA) && file_flush (handle, 0) == -1) + return -1; + +-- +2.47.3 + diff --git a/0004-common-include-test-once.c-Skip-test-on-macOS-which-.patch b/0004-common-include-test-once.c-Skip-test-on-macOS-which-.patch new file mode 100644 index 0000000..22a3b50 --- /dev/null +++ b/0004-common-include-test-once.c-Skip-test-on-macOS-which-.patch @@ -0,0 +1,63 @@ +From 48869f1c0b6e4c318b680f6f672a9f90dfe31bff Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 8 Jul 2025 21:39:04 +0100 +Subject: [PATCH] common/include/test-once.c: Skip test on macOS which lacks + pthread_barrier_t + +See: +https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap02.html +(cherry picked from commit 8271f9244f1521c716460820d8162e7641018674) +--- + common/include/test-once.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/common/include/test-once.c b/common/include/test-once.c +index d7dd5c42..512b1a20 100644 +--- a/common/include/test-once.c ++++ b/common/include/test-once.c +@@ -34,29 +34,29 @@ + + #include + #include ++#include ++#include + +-#ifndef HAVE_STDATOMIC_H ++#if !defined(HAVE_STDATOMIC_H) || !defined(_POSIX_BARRIERS) + +-/* Skip the test if no */ ++/* Skip the test if no or pthread_barrier_t */ + + int + main (void) + { +- printf ("SKIP: no on this platform\n"); ++ fprintf (stderr, ++ "SKIP: no or pthread_barrier_t on this platform\n"); + exit (77); + } + +-#else /* HAVE_STDATOMIC_H */ ++#else + + #include + #include +-#include + + #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */ + #include + +-#include +- + #include "once.h" + + #define NR_THREADS 8 +@@ -123,4 +123,4 @@ main (void) + exit (EXIT_SUCCESS); + } + +-#endif /* HAVE_STDATOMIC_H */ ++#endif +-- +2.47.3 + diff --git a/0005-common-include-test-once.c-Further-fixes-for-pthread.patch b/0005-common-include-test-once.c-Further-fixes-for-pthread.patch new file mode 100644 index 0000000..6f1dc7c --- /dev/null +++ b/0005-common-include-test-once.c-Further-fixes-for-pthread.patch @@ -0,0 +1,57 @@ +From f694d06d432d10699e26b2234f7a285fc018e94c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 9 Jul 2025 12:20:34 +0100 +Subject: [PATCH] common/include/test-once.c: Further fixes for + pthread_barrier_t + +macOS defines _POSIX_BARRIERS but turns out to lack any implementation +of pthread_barrier_t. WTF. + +FreeBSD requires linking with pthread else we get: + + ld: error: undefined symbol: pthread_barrier_init + +Fixes: commit ad8630deab4639e636212f11a5a47d2c34ef2949 +Fixes: commit 8271f9244f1521c716460820d8162e7641018674 +(cherry picked from commit 0d0e2b3d49cf8c9aa8cd37bb36b7002eb4624a2c) +--- + common/include/Makefile.am | 3 ++- + common/include/test-once.c | 7 +++++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/common/include/Makefile.am b/common/include/Makefile.am +index 3a3757e2..00a01091 100644 +--- a/common/include/Makefile.am ++++ b/common/include/Makefile.am +@@ -124,7 +124,8 @@ test_nextnonzero_CFLAGS = $(WARNINGS_CFLAGS) + + test_once_SOURCES = test-once.c once.h + test_once_CPPFLAGS = -I$(srcdir) +-test_once_CFLAGS = $(WARNINGS_CFLAGS) ++test_once_CFLAGS = $(WARNINGS_CFLAGS) $(PTHREAD_CFLAGS) ++test_once_LDFLAGS = $(PTHREAD_LIBS) + + test_random_SOURCES = test-random.c random.h + test_random_CPPFLAGS = -I$(srcdir) +diff --git a/common/include/test-once.c b/common/include/test-once.c +index 512b1a20..304d512a 100644 +--- a/common/include/test-once.c ++++ b/common/include/test-once.c +@@ -37,9 +37,12 @@ + #include + #include + +-#if !defined(HAVE_STDATOMIC_H) || !defined(_POSIX_BARRIERS) ++#if !defined(HAVE_STDATOMIC_H) || !defined(_POSIX_BARRIERS) || \ ++ defined(__APPLE__) + +-/* Skip the test if no or pthread_barrier_t */ ++/* Skip the test if no or pthread_barrier_t or on macOS ++ * which defines _POSIX_BARRIERS but doesn't actually have them. ++ */ + + int + main (void) +-- +2.47.3 + diff --git a/0006-Remove-deprecated-cacheextents-filter.patch b/0006-Remove-deprecated-cacheextents-filter.patch new file mode 100644 index 0000000..0723b62 --- /dev/null +++ b/0006-Remove-deprecated-cacheextents-filter.patch @@ -0,0 +1,692 @@ +From dc8c6aae6aa1c62083421e2b2ce2988e970f2579 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 1 Jul 2025 13:26:08 +0100 +Subject: [PATCH] Remove deprecated cacheextents filter + +This is removed along the development branch (1.45) and in the next +stable version of nbdkit (1.46). + +(cherry picked from commit 886050f6de9179b0e267e15b20376313090b2d3c) +--- + configure.ac | 2 - + docs/nbdkit-protocol.pod | 9 +- + docs/nbdkit-release-notes-1.14.pod | 2 +- + docs/nbdkit-release-notes-1.44.pod | 2 +- + filters/cache/nbdkit-cache-filter.pod | 8 +- + filters/cacheextents/Makefile.am | 74 ------ + filters/cacheextents/cacheextents.c | 212 ------------------ + .../nbdkit-cacheextents-filter.pod | 76 ------- + filters/cow/nbdkit-cow-filter.pod | 1 - + .../extentlist/nbdkit-extentlist-filter.pod | 1 - + tests/Makefile.am | 4 - + tests/test-cacheextents.sh | 114 ---------- + 12 files changed, 9 insertions(+), 496 deletions(-) + delete mode 100644 filters/cacheextents/Makefile.am + delete mode 100644 filters/cacheextents/cacheextents.c + delete mode 100644 filters/cacheextents/nbdkit-cacheextents-filter.pod + delete mode 100755 tests/test-cacheextents.sh + +diff --git a/configure.ac b/configure.ac +index 0dca333f..9b057e6f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -143,7 +143,6 @@ filters="\ + blocksize-policy \ + bzip2 \ + cache \ +- cacheextents \ + checkwrite \ + cow \ + ddrescue \ +@@ -1787,7 +1786,6 @@ AC_CONFIG_FILES([Makefile + filters/blocksize-policy/Makefile + filters/bzip2/Makefile + filters/cache/Makefile +- filters/cacheextents/Makefile + filters/checkwrite/Makefile + filters/cow/Makefile + filters/ddrescue/Makefile +diff --git a/docs/nbdkit-protocol.pod b/docs/nbdkit-protocol.pod +index ef1934fd..93f5c5fa 100644 +--- a/docs/nbdkit-protocol.pod ++++ b/docs/nbdkit-protocol.pod +@@ -275,14 +275,13 @@ filters do not work properly in this case. + blocksize-policy Yes + bzip2 No + cache No +- cacheextents No + checkwrite Yes + cow Yes, since 1.44 + delay Yes + error Yes + evil Yes +- + exitlast Yes ++ + exitwhen Yes + exportname Yes + ext2 No +@@ -292,8 +291,8 @@ filters do not work properly in this case. + ip Yes + limit Yes + log Yes +- + luks No ++ + lzip No + multi-conn Yes + nocache Yes +@@ -303,8 +302,8 @@ filters do not work properly in this case. + nozero Yes + offset Yes, but unlikely to be useful + openonce Yes +- + partition No ++ + pause Yes + protect Yes, but unlikely to be useful + qcow2dec No +@@ -314,8 +313,8 @@ filters do not work properly in this case. + retry Yes + retry-request Yes + rotational Yes +- + scan Yes ++ + spinning Yes + stats Yes + swab Yes +diff --git a/docs/nbdkit-release-notes-1.14.pod b/docs/nbdkit-release-notes-1.14.pod +index 627e7e88..3c8c5d53 100644 +--- a/docs/nbdkit-release-notes-1.14.pod ++++ b/docs/nbdkit-release-notes-1.14.pod +@@ -50,7 +50,7 @@ plugin’s own choice of thread model. Used to determine how the thread + model affects performance, or to serialize plugins if required (Eric + Blake). + +-New L to cache extents requests, ++New nbdkit-cacheextents-filter to cache extents requests, + especially useful with VDDK which has a slow implementation of extents + (Martin Kletzander). + +diff --git a/docs/nbdkit-release-notes-1.44.pod b/docs/nbdkit-release-notes-1.44.pod +index 62d69aa5..e5872763 100644 +--- a/docs/nbdkit-release-notes-1.44.pod ++++ b/docs/nbdkit-release-notes-1.44.pod +@@ -59,7 +59,7 @@ eg. C<@4M> to move the offset to 4194304 (Eric Blake). + New L which can be used to open the + underlying plugin once, sharing the plugin across connections. + +-L I, and is ++I, and is + expected to be removed in S. + + L now understands that the NBD protocol export +diff --git a/filters/cache/nbdkit-cache-filter.pod b/filters/cache/nbdkit-cache-filter.pod +index ffa86919..7a64ca66 100644 +--- a/filters/cache/nbdkit-cache-filter.pod ++++ b/filters/cache/nbdkit-cache-filter.pod +@@ -29,10 +29,9 @@ does not have effective caching, or (with C) to defeat + flush requests from the client (which is unsafe and can cause data + loss, as the name suggests). + +-This filter only caches image contents. To cache image metadata, use +-L between this filter and the plugin. +-To accelerate sequential reads, use L or +-L on top of this filter. ++This filter only caches image contents. To accelerate sequential ++reads, use L or L ++on top of this filter. + + =head1 PARAMETERS + +@@ -181,7 +180,6 @@ C first appeared in nbdkit 1.2. + + L, + L, +-L, + L, + L, + L, +diff --git a/filters/cacheextents/Makefile.am b/filters/cacheextents/Makefile.am +deleted file mode 100644 +index 26ac6642..00000000 +--- a/filters/cacheextents/Makefile.am ++++ /dev/null +@@ -1,74 +0,0 @@ +-# 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. +- +-include $(top_srcdir)/common-rules.mk +- +-EXTRA_DIST = nbdkit-cacheextents-filter.pod +- +-filter_LTLIBRARIES = nbdkit-cacheextents-filter.la +- +-nbdkit_cacheextents_filter_la_SOURCES = \ +- cacheextents.c \ +- $(top_srcdir)/include/nbdkit-filter.h \ +- $(NULL) +- +-nbdkit_cacheextents_filter_la_CPPFLAGS = \ +- -I$(top_srcdir)/include \ +- -I$(top_builddir)/include \ +- -I$(top_srcdir)/common/include \ +- -I$(top_srcdir)/common/utils \ +- $(NULL) +-nbdkit_cacheextents_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +-nbdkit_cacheextents_filter_la_LDFLAGS = \ +- -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ +- $(NULL) +-if USE_LINKER_SCRIPT +-nbdkit_cacheextents_filter_la_LDFLAGS += \ +- -Wl,--version-script=$(top_srcdir)/filters/filters.syms +-endif +-nbdkit_cacheextents_filter_la_LIBADD = \ +- $(top_builddir)/common/utils/libutils.la \ +- $(top_builddir)/common/replacements/libcompat.la \ +- $(IMPORT_LIBRARY_ON_WINDOWS) \ +- $(NULL) +- +-if HAVE_POD +- +-man_MANS = nbdkit-cacheextents-filter.1 +-CLEANFILES += $(man_MANS) +- +-nbdkit-cacheextents-filter.1: nbdkit-cacheextents-filter.pod \ +- $(top_builddir)/podwrapper.pl +- $(PODWRAPPER) --section=1 --man $@ \ +- --html $(top_builddir)/html/$@.html \ +- $< +- +-endif HAVE_POD +diff --git a/filters/cacheextents/cacheextents.c b/filters/cacheextents/cacheextents.c +deleted file mode 100644 +index 71f73c41..00000000 +--- a/filters/cacheextents/cacheextents.c ++++ /dev/null +@@ -1,212 +0,0 @@ +-/* 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. +- */ +- +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include +- +-#include "cleanup.h" +- +-/* -D cacheextents.cache=1: Debug cache operations. */ +-NBDKIT_DLL_PUBLIC int cacheextents_debug_cache = 0; +- +-/* This lock protects the global state. */ +-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +- +-/* Cached extents from the last extents () call and its start and end +- * for the sake of simplicity. +- */ +-struct nbdkit_extents *cache_extents; +-static uint64_t cache_start; +-static uint64_t cache_end; +- +-static void +-cacheextents_unload (void) +-{ +- nbdkit_extents_free (cache_extents); +-} +- +-static int +-cacheextents_add (struct nbdkit_extents *extents, int *err) +-{ +- size_t i = 0; +- +- for (i = 0; i < nbdkit_extents_count (cache_extents); i++) { +- struct nbdkit_extent ex = nbdkit_get_extent (cache_extents, i); +- if (nbdkit_add_extent (extents, ex.offset, ex.length, ex.type) == -1) { +- *err = errno; +- return -1; +- } +- } +- +- return 0; +-} +- +-static int +-fill (struct nbdkit_extents *extents, int *err) +-{ +- size_t i = 0; +- size_t count = nbdkit_extents_count (extents); +- struct nbdkit_extent first = nbdkit_get_extent (extents, 0); +- struct nbdkit_extent last = nbdkit_get_extent (extents, count - 1); +- +- nbdkit_extents_free (cache_extents); +- cache_start = first.offset; +- cache_end = last.offset + last.length; +- cache_extents = nbdkit_extents_new (cache_start, cache_end); +- +- if (!cache_extents) +- return -1; +- +- for (i = 0; i < count; i++) { +- struct nbdkit_extent ex = nbdkit_get_extent (extents, i); +- +- if (cacheextents_debug_cache) +- nbdkit_debug ("cacheextents: updating cache with:" +- " offset=%" PRIu64 +- " length=%" PRIu64 +- " type=%x", +- ex.offset, ex.length, ex.type); +- +- if (nbdkit_add_extent (cache_extents, ex.offset, ex.length, +- ex.type) == -1) { +- *err = errno; +- nbdkit_extents_free (cache_extents); +- cache_extents = NULL; +- return -1; +- } +- } +- +- return 0; +-} +- +-static int +-cacheextents_extents (nbdkit_next *next, +- void *handle, uint32_t count, uint64_t offset, +- uint32_t flags, +- struct nbdkit_extents *extents, +- int *err) +-{ +- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock); +- +- if (cacheextents_debug_cache) +- nbdkit_debug ("cacheextents:" +- " cache_start=%" PRIu64 +- " cache_end=%" PRIu64 +- " cache_extents=%p", +- cache_start, cache_end, cache_extents); +- +- if (cache_extents && +- offset >= cache_start && offset < cache_end) { +- if (cacheextents_debug_cache) +- nbdkit_debug ("cacheextents: returning from cache"); +- return cacheextents_add (extents, err); +- } +- +- if (cacheextents_debug_cache) +- nbdkit_debug ("cacheextents: cache miss"); +- +- /* Clear REQ_ONE to ask the plugin for as much information as it is +- * willing to return (the plugin may still truncate if it is too +- * costly to provide everything). +- */ +- flags &= ~(NBDKIT_FLAG_REQ_ONE); +- if (next->extents (next, count, offset, flags, extents, err) == -1) +- return -1; +- +- return fill (extents, err); +-} +- +-/* Any changes to the data needs to clean the cache. +- * +- * Similar to the readahead filter this could be more intelligent, but +- * there would be very little benefit. +- */ +- +-static void +-kill_cacheextents (void) +-{ +- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock); +- nbdkit_extents_free (cache_extents); +- cache_extents = NULL; +-} +- +-static int +-cacheextents_pwrite (nbdkit_next *next, +- void *handle, +- const void *buf, uint32_t count, uint64_t offset, +- uint32_t flags, int *err) +-{ +- kill_cacheextents (); +- return next->pwrite (next, buf, count, offset, flags, err); +-} +- +-static int +-cacheextents_trim (nbdkit_next *next, +- void *handle, +- uint32_t count, uint64_t offset, uint32_t flags, +- int *err) +-{ +- kill_cacheextents (); +- return next->trim (next, count, offset, flags, err); +-} +- +-static int +-cacheextents_zero (nbdkit_next *next, +- void *handle, +- uint32_t count, uint64_t offset, uint32_t flags, +- int *err) +-{ +- kill_cacheextents (); +- return next->zero (next, count, offset, flags, err); +-} +- +-static struct nbdkit_filter filter = { +- .name = "cacheextents", +- .longname = "nbdkit cacheextents filter", +- .unload = cacheextents_unload, +- .pwrite = cacheextents_pwrite, +- .trim = cacheextents_trim, +- .zero = cacheextents_zero, +- .extents = cacheextents_extents, +-}; +- +-NBDKIT_REGISTER_FILTER (filter) +diff --git a/filters/cacheextents/nbdkit-cacheextents-filter.pod b/filters/cacheextents/nbdkit-cacheextents-filter.pod +deleted file mode 100644 +index 0693ca80..00000000 +--- a/filters/cacheextents/nbdkit-cacheextents-filter.pod ++++ /dev/null +@@ -1,76 +0,0 @@ +-=head1 NAME +- +-nbdkit-cacheextents-filter - cache extents +- +-=head1 SYNOPSIS +- +- nbdkit --filter=cacheextents plugin +- +-=head1 DEPRECATED +- +-B 1.43.10> and +-will be removed in S>. There is no direct replacement, +-but as the filter only worked for a narrow and unusual range of access +-patterns it is likely that it has no effect and you can just stop +-using it. +- +-=head1 DESCRIPTION +- +-C is a filter that caches the result of last +-extents() call. +- +-A common use for this filter is to improve performance when using a +-client performing a linear pass over the entire image while asking for +-only one extent at a time (such as S>), but where +-the plugin can provide multiple extents for the same high latency as a +-single extent (such as L). For example: +- +- nbdkit --filter=cacheextents --run 'qemu-img map "$uri"' vddk ... +- +-For files with big extents (when it is unlikely for one extents() call +-to return multiple different extents) this does not slow down the +-access. +- +-This filter only caches image metadata; to also cache image contents, +-place this filter between L and the plugin. +- +-=head1 PARAMETERS +- +-There are no parameters specific to nbdkit-cacheextents-filter. Any +-parameters are passed through to and processed by the underlying +-plugin in the normal way. +- +-=head1 FILES +- +-=over 4 +- +-=item F<$filterdir/nbdkit-cacheextents-filter.so> +- +-The filter. +- +-Use C to find the location of C<$filterdir>. +- +-=back +- +-=head1 VERSION +- +-C first appeared in nbdkit 1.14. +- +-=head1 SEE ALSO +- +-L, +-L, +-L, +-L, +-L, +-L, +-L, +-L. +- +-=head1 AUTHORS +- +-Martin Kletzander +- +-=head1 COPYRIGHT +- +-Copyright Red Hat +diff --git a/filters/cow/nbdkit-cow-filter.pod b/filters/cow/nbdkit-cow-filter.pod +index fd551d93..9462a28d 100644 +--- a/filters/cow/nbdkit-cow-filter.pod ++++ b/filters/cow/nbdkit-cow-filter.pod +@@ -169,7 +169,6 @@ C first appeared in nbdkit 1.2. + L, + L, + L, +-L, + L, + L, + L, +diff --git a/filters/extentlist/nbdkit-extentlist-filter.pod b/filters/extentlist/nbdkit-extentlist-filter.pod +index d5ac81eb..44c81635 100644 +--- a/filters/extentlist/nbdkit-extentlist-filter.pod ++++ b/filters/extentlist/nbdkit-extentlist-filter.pod +@@ -85,7 +85,6 @@ C first appeared in nbdkit 1.18. + =head1 SEE ALSO + + L, +-L, + L, + L, + L. +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 6d94c327..c16b5912 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1694,10 +1694,6 @@ EXTRA_DIST += \ + test-cache-unaligned.sh \ + $(NULL) + +-# cacheextents filter test. +-TESTS += test-cacheextents.sh +-EXTRA_DIST += test-cacheextents.sh +- + # checkwrite filter test. + TESTS += \ + test-checkwrite.sh \ +diff --git a/tests/test-cacheextents.sh b/tests/test-cacheextents.sh +deleted file mode 100755 +index 34d66217..00000000 +--- a/tests/test-cacheextents.sh ++++ /dev/null +@@ -1,114 +0,0 @@ +-#!/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. +- +-source ./functions.sh +-set -x +-set -u +-set -e +- +-requires_plugin sh +-requires_filter cacheextents +-requires grep --version +-requires qemu-io --version +-requires dd iflag=count_bytes >$accessfile_full +-size=4M +-block_size=$((1024*1024)) +-case "$1" in +- thread_model) echo parallel ;; +- get_size) echo $size ;; +- can_extents) ;; +- extents) +- echo "extents request: $@" >>$accessfile_full +- offset=$(($4 / $block_size)) +- count=$(($3 / $block_size)) +- length=$(($offset + $count)) +- for i in $(seq $offset $length); do +- echo ${i}M $block_size $((i%4)) >>$accessfile_full +- echo ${i}M $block_size $((i%4)) +- done +- ;; +- pread) dd if=/dev/zero count=$3 iflag=count_bytes ;; +- can_write) ;; +- pwrite) dd of=/dev/null ;; +- can_trim) ;; +- trim) ;; +- can_zero) ;; +- zero) ;; +- *) exit 2 ;; +-esac +-EOF +- +-export accessfile_full +-start_nbdkit \ +- -P $pidfile \ +- -U $sock \ +- --filter=cacheextents \ +- sh - <<<"$plugin" +- +-test_me() { +- num_accesses=$1 +- shift +- +- qemu-io -f raw "$@" "$sockurl" +- test "$(grep -c "^extents request: " $accessfile)" -eq "$num_accesses" +- ret=$? +- rm -f "$accessfile" +- return $ret +-} +- +-# First one causes caching, the rest should be returned from cache. +-test_me 1 -c 'map' -c 'map' -c 'map' +-# First one is still cached from last time, discard should kill the cache, then +-# one request should go through. +-test_me 1 -c 'map' -c 'discard 0 1' -c 'map' +-# Same as above, only this time the cache is killed before all the operations as +-# well. This is used from now on to clear the cache as it seems nicer and +-# faster than running new nbdkit for each test. +-test_me 2 -c 'discard 0 1' -c 'map' -c 'discard 0 1' -c 'map' +-# Write should kill the cache as well. +-test_me 2 -c 'discard 0 1' -c 'map' -c 'write 0 1' -c 'map' +-# Alloc should use cached data from map +-test_me 1 -c 'discard 0 1' -c 'map' -c 'alloc 0' +-# Read should not kill the cache +-test_me 1 -c 'discard 0 1' -c 'map' -c 'read 0 1' -c 'map' -c 'alloc 0' +-- +2.47.3 + diff --git a/0007-New-filter-nbdkit-count-filter-count-bytes-read-writ.patch b/0007-New-filter-nbdkit-count-filter-count-bytes-read-writ.patch new file mode 100644 index 0000000..f8de372 --- /dev/null +++ b/0007-New-filter-nbdkit-count-filter-count-bytes-read-writ.patch @@ -0,0 +1,500 @@ +From 9c28df70cbde94e58e448c8953965510e5d952c2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 8 Jul 2025 17:49:00 +0100 +Subject: [PATCH] New filter: nbdkit-count-filter: count bytes read, written + etc. + +This produces a summary of the number of bytes read, written, etc +through the filter. + +This is mainly of use to virt-v2v where it's commonly asked how much +data was transferred over the wire or written to disk, and we don't +currently have an easy way to answer that. By simply adding this +filter, the numbers will be known from the virt-v2v conversion log. + +(cherry picked from commit 3512c3ce9308b4d940119ac6cc87f1baa9afb655) +--- + configure.ac | 2 + + docs/nbdkit-protocol.pod | 9 +- + filters/count/Makefile.am | 70 ++++++++++++++ + filters/count/count.c | 132 ++++++++++++++++++++++++++ + filters/count/nbdkit-count-filter.pod | 55 +++++++++++ + filters/log/nbdkit-log-filter.pod | 1 + + filters/stats/nbdkit-stats-filter.pod | 3 + + plugins/file/nbdkit-file-plugin.pod | 1 + + tests/Makefile.am | 4 + + tests/test-count.sh | 55 +++++++++++ + 10 files changed, 328 insertions(+), 4 deletions(-) + create mode 100644 filters/count/Makefile.am + create mode 100644 filters/count/count.c + create mode 100644 filters/count/nbdkit-count-filter.pod + create mode 100755 tests/test-count.sh + +diff --git a/configure.ac b/configure.ac +index 9b057e6f..26e59462 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -144,6 +144,7 @@ filters="\ + bzip2 \ + cache \ + checkwrite \ ++ count \ + cow \ + ddrescue \ + delay \ +@@ -1787,6 +1788,7 @@ AC_CONFIG_FILES([Makefile + filters/bzip2/Makefile + filters/cache/Makefile + filters/checkwrite/Makefile ++ filters/count/Makefile + filters/cow/Makefile + filters/ddrescue/Makefile + filters/delay/Makefile +diff --git a/docs/nbdkit-protocol.pod b/docs/nbdkit-protocol.pod +index 93f5c5fa..edf0efb0 100644 +--- a/docs/nbdkit-protocol.pod ++++ b/docs/nbdkit-protocol.pod +@@ -276,12 +276,13 @@ filters do not work properly in this case. + bzip2 No + cache No + checkwrite Yes ++ count Yes + cow Yes, since 1.44 + delay Yes + error Yes + evil Yes ++ + exitlast Yes +- + exitwhen Yes + exportname Yes + ext2 No +@@ -291,8 +292,8 @@ filters do not work properly in this case. + ip Yes + limit Yes + log Yes ++ + luks No +- + lzip No + multi-conn Yes + nocache Yes +@@ -302,8 +303,8 @@ filters do not work properly in this case. + nozero Yes + offset Yes, but unlikely to be useful + openonce Yes ++ + partition No +- + pause Yes + protect Yes, but unlikely to be useful + qcow2dec No +@@ -313,8 +314,8 @@ filters do not work properly in this case. + retry Yes + retry-request Yes + rotational Yes ++ + scan Yes +- + spinning Yes + stats Yes + swab Yes +diff --git a/filters/count/Makefile.am b/filters/count/Makefile.am +new file mode 100644 +index 00000000..20456e17 +--- /dev/null ++++ b/filters/count/Makefile.am +@@ -0,0 +1,70 @@ ++# 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. ++ ++include $(top_srcdir)/common-rules.mk ++ ++EXTRA_DIST = nbdkit-count-filter.pod ++ ++filter_LTLIBRARIES = nbdkit-count-filter.la ++ ++nbdkit_count_filter_la_SOURCES = \ ++ count.c \ ++ $(top_srcdir)/include/nbdkit-filter.h \ ++ $(NULL) ++ ++nbdkit_count_filter_la_CPPFLAGS = \ ++ -I$(top_srcdir)/include \ ++ -I$(top_builddir)/include \ ++ $(NULL) ++nbdkit_count_filter_la_CFLAGS = $(WARNINGS_CFLAGS) ++nbdkit_count_filter_la_LDFLAGS = \ ++ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ ++ $(NULL) ++if USE_LINKER_SCRIPT ++nbdkit_count_filter_la_LDFLAGS += \ ++ -Wl,--version-script=$(top_srcdir)/filters/filters.syms ++endif ++nbdkit_count_filter_la_LIBADD = \ ++ $(IMPORT_LIBRARY_ON_WINDOWS) \ ++ $(NULL) ++ ++if HAVE_POD ++ ++man_MANS = nbdkit-count-filter.1 ++CLEANFILES += $(man_MANS) ++ ++nbdkit-count-filter.1: nbdkit-count-filter.pod \ ++ $(top_builddir)/podwrapper.pl ++ $(PODWRAPPER) --section=1 --man $@ \ ++ --html $(top_builddir)/html/$@.html \ ++ $< ++ ++endif HAVE_POD +diff --git a/filters/count/count.c b/filters/count/count.c +new file mode 100644 +index 00000000..8af7f5a0 +--- /dev/null ++++ b/filters/count/count.c +@@ -0,0 +1,132 @@ ++/* 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. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#ifdef HAVE_STDATOMIC_H ++#include ++#else ++/* Only used for counting statistics. */ ++#define _Atomic /**/ ++#endif ++ ++static _Atomic uint64_t bytes_read, bytes_written, bytes_zeroed, bytes_trimmed; ++ ++static void ++count_unload (void) ++{ ++ nbdkit_debug ("count bytes: " ++ "read %" PRIu64 ", " ++ "written %" PRIu64 ", " ++ "zeroed %" PRIu64 ", " ++ "trimmed %" PRIu64, ++ bytes_read, bytes_written, bytes_zeroed, bytes_trimmed); ++} ++ ++/* Read data. */ ++static int ++count_pread (nbdkit_next *next, ++ void *handle, ++ void *buf, ++ uint32_t count, uint64_t offset, uint32_t flags, ++ int *err) ++{ ++ int r; ++ ++ r = next->pread (next, buf, count, offset, flags, err); ++ if (r >= 0) ++ bytes_read += count; ++ return r; ++} ++ ++/* Write data. */ ++static int ++count_pwrite (nbdkit_next *next, ++ void *handle, ++ const void *buf, ++ uint32_t count, uint64_t offset, uint32_t flags, ++ int *err) ++{ ++ int r; ++ ++ r = next->pwrite (next, buf, count, offset, flags, err); ++ if (r >= 0) ++ bytes_written += count; ++ return r; ++} ++ ++/* Trim data. */ ++static int ++count_trim (nbdkit_next *next, ++ void *handle, uint32_t count, uint64_t offset, uint32_t flags, ++ int *err) ++{ ++ int r; ++ ++ r = next->trim (next, count, offset, flags, err); ++ if (r >= 0) ++ bytes_trimmed += count; ++ return r; ++} ++ ++/* Zero data. */ ++static int ++count_zero (nbdkit_next *next, ++ void *handle, uint32_t count, uint64_t offset, uint32_t flags, ++ int *err) ++{ ++ int r; ++ ++ r = next->zero (next, count, offset, flags, err); ++ if (r >= 0) ++ bytes_zeroed += count; ++ return r; ++} ++ ++static struct nbdkit_filter filter = { ++ .name = "count", ++ .longname = "nbdkit count filter", ++ .unload = count_unload, ++ .pread = count_pread, ++ .pwrite = count_pwrite, ++ .trim = count_trim, ++ .zero = count_zero, ++}; ++ ++NBDKIT_REGISTER_FILTER (filter) +diff --git a/filters/count/nbdkit-count-filter.pod b/filters/count/nbdkit-count-filter.pod +new file mode 100644 +index 00000000..f0437000 +--- /dev/null ++++ b/filters/count/nbdkit-count-filter.pod +@@ -0,0 +1,55 @@ ++=head1 NAME ++ ++nbdkit-count-filter - count bytes read, written, zeroed and trimmed ++ ++=head1 SYNOPSIS ++ ++ nbdkit --filter=count plugin ++ ++=head1 DESCRIPTION ++ ++C is a filter for L that simply counts ++the number of bytes that are read, written, zeroed and trimmed, and ++reports this number in debugging output when the filter is unloaded ++(usually when nbdkit exits). ++ ++This is a very simple and lightweight filter. For much more ++comprehensive stats about and logging of operations, use ++L or L instead. ++ ++=head1 PARAMETERS ++ ++There are no parameters specific to this filter. All parameters are ++passed through to the underlying plugin. ++ ++=head1 FILES ++ ++=over 4 ++ ++=item F<$filterdir/nbdkit-count-filter.so> ++ ++The filter. ++ ++Use C to find the location of C<$filterdir>. ++ ++=back ++ ++=head1 VERSION ++ ++C first appeared 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/filters/log/nbdkit-log-filter.pod b/filters/log/nbdkit-log-filter.pod +index b91b60c4..256701a1 100644 +--- a/filters/log/nbdkit-log-filter.pod ++++ b/filters/log/nbdkit-log-filter.pod +@@ -208,6 +208,7 @@ L, + L, + L, + L, ++L, + L. + + =head1 AUTHORS +diff --git a/filters/stats/nbdkit-stats-filter.pod b/filters/stats/nbdkit-stats-filter.pod +index c0d2b45c..10074b4a 100644 +--- a/filters/stats/nbdkit-stats-filter.pod ++++ b/filters/stats/nbdkit-stats-filter.pod +@@ -13,6 +13,8 @@ C is a filter that displays statistics about NBD + operations, such as the number of bytes read and written. Statistics + are written to a file once when nbdkit exits. + ++A lighter weight version of this is L. ++ + =head1 EXAMPLE OUTPUT + + # nbdkit --filter=exitlast --filter=stats memory 25G statsfile=example.txt +@@ -113,6 +115,7 @@ C first appeared in nbdkit 1.14. + + L, + L, ++L, + L. + + =head1 AUTHORS +diff --git a/plugins/file/nbdkit-file-plugin.pod b/plugins/file/nbdkit-file-plugin.pod +index 63d07617..626827b2 100644 +--- a/plugins/file/nbdkit-file-plugin.pod ++++ b/plugins/file/nbdkit-file-plugin.pod +@@ -316,6 +316,7 @@ L, + L, + L, + L, ++L, + L, + L, + L, +diff --git a/tests/Makefile.am b/tests/Makefile.am +index c16b5912..d7053ba2 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1706,6 +1706,10 @@ EXTRA_DIST += \ + test-checkwrite-fail.sh \ + $(NULL) + ++# count filter test. ++TESTS += test-count.sh ++EXTRA_DIST += test-count.sh ++ + # cow filter test. + if HAVE_MKE2FS_WITH_D + TESTS += \ +diff --git a/tests/test-count.sh b/tests/test-count.sh +new file mode 100755 +index 00000000..e2e10704 +--- /dev/null ++++ b/tests/test-count.sh +@@ -0,0 +1,55 @@ ++#!/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-count-filter. ++ ++source ./functions.sh ++set -e ++set -x ++set -u ++ ++requires_run ++requires_filter count ++requires_plugin sparse-random ++requires_nbdcopy ++ ++log=test-count.out ++rm -f $log ++cleanup_fn rm -f $log ++ ++# We use sparse-random plugin because it both provides some data for ++# nbdcopy to copy, and allows writes. ++nbdkit -v --filter=count sparse-random 1G \ ++ --run 'nbdcopy "$uri" "$uri"' 2>$log ++ ++# Check that something got logged when the filter was unloaded. ++grep "count bytes:" $log +-- +2.47.3 + diff --git a/0008-count-Clarify-documentation.patch b/0008-count-Clarify-documentation.patch new file mode 100644 index 0000000..79e0973 --- /dev/null +++ b/0008-count-Clarify-documentation.patch @@ -0,0 +1,41 @@ +From 745b959b44a67cd3def7c60b873701ad79137bda Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 8 Jul 2025 21:20:52 +0100 +Subject: [PATCH] count: Clarify documentation + +Updates: commit 3512c3ce9308b4d940119ac6cc87f1baa9afb655 +(cherry picked from commit 7c84314ec7411fc1090bf1ca417c453d08fcf364) +--- + filters/count/nbdkit-count-filter.pod | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/filters/count/nbdkit-count-filter.pod b/filters/count/nbdkit-count-filter.pod +index f0437000..c20b4737 100644 +--- a/filters/count/nbdkit-count-filter.pod ++++ b/filters/count/nbdkit-count-filter.pod +@@ -4,17 +4,19 @@ nbdkit-count-filter - count bytes read, written, zeroed and trimmed + + =head1 SYNOPSIS + +- nbdkit --filter=count plugin ++ nbdkit -fv --filter=count plugin + + =head1 DESCRIPTION + + C is a filter for L that simply counts + the number of bytes that are read, written, zeroed and trimmed, and + reports this number in debugging output when the filter is unloaded +-(usually when nbdkit exits). ++(usually when nbdkit exits). The filter output can only be seen when ++debugging is enabled (I<-v>) which usually implies using the ++foreground (I<-f>) option as well. + + This is a very simple and lightweight filter. For much more +-comprehensive stats about and logging of operations, use ++comprehensive stats and logging of operations, use + L or L instead. + + =head1 PARAMETERS +-- +2.47.3 + diff --git a/0009-vddk-Don-t-use-FNM_PATHNAME-when-matching-export-par.patch b/0009-vddk-Don-t-use-FNM_PATHNAME-when-matching-export-par.patch new file mode 100644 index 0000000..2a2a9f5 --- /dev/null +++ b/0009-vddk-Don-t-use-FNM_PATHNAME-when-matching-export-par.patch @@ -0,0 +1,109 @@ +From 65b6b241dcac900e996171897b46fecb6551cd27 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 20 Oct 2025 11:35:51 +0100 +Subject: [PATCH] vddk: Don't use FNM_PATHNAME when matching export parameter + +Commit 18866d92d1 ("vddk: Add export parameter") added recently allows +a single VDDK plugin instance to serve multiple files on the VMware +server. The NBD client chooses which file to serve by sending an NBD +export name. + +As a mild protection against an attacker who has access to the NBD +endpoint from requesting any file from the server (and not just those +related to a single virtual machine), you are able to specify an +export wildcard. The NBD export name from the client is compared to +the wildcard before allowing the connection to read anything. + +The wildcard was matched (before this commit) using: + + fnmatch (export_wildcard, nbd_export_name, FNM_PATHNAME) + +As a concrete example: + + - Virtual machine with two disks called: + "[esx] esx-win11/esx-win11.vmdk" + "[esx] esx-win11/esx-win11-2.vmdk" + + - nbdkit vddk export="\[esx\] esx-win11/*.vmdk" + +NBD client requests "[esx] esx-win11/esx-win11.vmdk" => allowed +(because this export name matches the wildcard). + +NBD client requests "[esx] unrelated guest/disk.vmdk" => denied +(because this export name does not match the wildcard). + +Note the effect of FNM_PATHNAME, as described in the man page: + + FNM_PATHNAME + If this flag is set, match a slash in string only with a slash in + pattern and not by an asterisk (*) or a question mark (?) + metacharacter, nor by a bracket expression ([]) containing a + slash. + +Now consider a different guest where the disks are located at +different subdirectory depths: + + - Virtual machine with two disks called: + "[esx] esx-win10/esx-win10.vmdk" + "[esx] esx-win10/disk2/esx-win10-2.vmdk" + + - nbdkit vddk export=??? + +It is not possible to construct an export wildcard that matches both +disk names, because the special character '/' in the export name must +match exactly one '/' in the wildcard, but the two paths have +different numbers of '/' characters. + +The best solution I can come up with for this is to relax the +restriction by removing the FNM_PATHNAME parameter of fnmatch. Thus +(after this commit is applied): + + - Virtual machine with two disks called: + "[esx] esx-win10/esx-win10.vmdk" + "[esx] esx-win10/disk2/esx-win10-2.vmdk" + + - nbdkit vddk export="\[esx\] esx-win10/*.vmdk" + +As part of this change, I also tested how "//" and "/../" in paths +behaves, so that we weren't opening up a hole where someone could +request "[esx] esx-win10/../unrelated guest/disk.vmdk". It turns out +that VMware does not parse these as paths. It seems to treat these +parameters only as simple strings, and any variation in the string is +rejected. + +Note also that the export wildcard is really a backstop in case +regular permissions on the NBD endpoint fail. It's not supposed to +offer complete security. + +Reported-by: Ming Xie +Related: https://issues.redhat.com/browse/RHEL-121728 +Related: https://github.com/libguestfs/virt-v2v/commit/ba86b22c75a65240fdb65ac2e91c472c0f68f78e +(cherry picked from commit 01b429c412504a491a4b5cc009a9c2e906f993ef) +--- + plugins/vddk/vddk.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c +index e16813e4..6c667dc7 100644 +--- a/plugins/vddk/vddk.c ++++ b/plugins/vddk/vddk.c +@@ -639,6 +639,7 @@ vddk_dump_plugin (void) + + printf ("vddk_default_libdir=%s\n", VDDK_LIBDIR); + printf ("vddk_has_nfchostport=1\n"); ++ printf ("vddk_has_fnm_pathname=0\n"); + + /* Because load_library (false) we might not have loaded VDDK, in + * which case we didn't set library_version. Note this cannot +@@ -744,7 +745,7 @@ vddk_open (int readonly) + goto err0; + } + +- r = fnmatch (export_wildcard, nbd_export_name, FNM_PATHNAME); ++ r = fnmatch (export_wildcard, nbd_export_name, 0); + switch (r) { + case 0: /* OK */ break; + case FNM_NOMATCH: +-- +2.47.3 + diff --git a/0010-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch b/0010-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch new file mode 100644 index 0000000..80891bd --- /dev/null +++ b/0010-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch @@ -0,0 +1,47 @@ +From b49ef5b2fa3482272082fa3ef34c55c567b8d8c6 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) +(cherry picked from commit 5db5982dc9b801fe37c0d4086724abc330656609) +--- + plugins/file/file.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/plugins/file/file.c b/plugins/file/file.c +index 66d03d4f..ce84b7ca 100644 +--- a/plugins/file/file.c ++++ b/plugins/file/file.c +@@ -728,6 +728,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/0011-file-Change-calculations-of-block-size-hints-for-blo.patch b/0011-file-Change-calculations-of-block-size-hints-for-blo.patch new file mode 100644 index 0000000..9473184 --- /dev/null +++ b/0011-file-Change-calculations-of-block-size-hints-for-blo.patch @@ -0,0 +1,91 @@ +From 1e059d8146908aa37046db4759665e51f97feaea 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) +(cherry picked from commit 07cbf8b7a1e94079946c36ab83c1ae75ac175d4e) +--- + plugins/file/file.c | 45 ++++++++++++++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 17 deletions(-) + +diff --git a/plugins/file/file.c b/plugins/file/file.c +index ce84b7ca..c0d5524c 100644 +--- a/plugins/file/file.c ++++ b/plugins/file/file.c +@@ -396,7 +396,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 +@@ -721,32 +721,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/SOURCES/0001-vddk-Include-stdbool.h.patch b/SOURCES/0001-vddk-Include-stdbool.h.patch deleted file mode 100644 index 816facf..0000000 --- a/SOURCES/0001-vddk-Include-stdbool.h.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9f86b51b4d8110ee82f2c67c3939c85ce0ec1ea9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 6 Jan 2025 15:22:05 +0000 -Subject: [PATCH] vddk: Include - -Since this file uses booleans. - -Acked-by: Eric Blake -(cherry picked from commit fe855addae44e45e2344a33bd3857c561587f12e) ---- - plugins/vddk/worker.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -index 467d00ca..5982fcea 100644 ---- a/plugins/vddk/worker.c -+++ b/plugins/vddk/worker.c -@@ -34,6 +34,7 @@ - - #include - #include -+#include - #include - #include - --- -2.43.0 - diff --git a/SOURCES/0002-vddk-Cache-the-disk-size-in-the-handle.patch b/SOURCES/0002-vddk-Cache-the-disk-size-in-the-handle.patch deleted file mode 100644 index 4a31dcc..0000000 --- a/SOURCES/0002-vddk-Cache-the-disk-size-in-the-handle.patch +++ /dev/null @@ -1,59 +0,0 @@ -From bfac699727ccf20757dcb5dc4ce1aff885025c9d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 6 Jan 2025 16:47:55 +0000 -Subject: [PATCH] vddk: Cache the disk size in the handle - -No functional change here, we're just making sure we have the disk -size (in bytes) available in the handle. - -Acked-by: Eric Blake -(cherry picked from commit 2ba76db4a048471e997e508715081a70356f94f3) ---- - plugins/vddk/vddk.c | 6 +++--- - plugins/vddk/vddk.h | 3 +++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 6d242515..7a830cf9 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -873,19 +873,19 @@ vddk_get_size (void *handle) - { - struct vddk_handle *h = handle; - VixDiskLibInfo *info; -- int64_t size; - struct command info_cmd = { .type = INFO, .ptr = &info }; - - if (send_command_and_wait (h, &info_cmd) == -1) - return -1; - -- size = info->capacity * (int64_t)VIXDISKLIB_SECTOR_SIZE; -+ /* Compute the size and cache it into the handle. */ -+ h->size = info->capacity * VIXDISKLIB_SECTOR_SIZE; - - VDDK_CALL_START (VixDiskLib_FreeInfo, "info") - VixDiskLib_FreeInfo (info); - VDDK_CALL_END (VixDiskLib_FreeInfo, 0); - -- return size; -+ return h->size; - } - - /* Advertise most efficient block sizes. */ -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index fb0c79a8..1d1069cc 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -165,6 +165,9 @@ struct vddk_handle { - command_queue commands; /* command queue */ - pthread_cond_t commands_cond; /* condition (queue size 0 -> 1) */ - uint64_t id; /* next command ID */ -+ -+ /* Cached disk size in bytes (set in get_size()). */ -+ uint64_t size; - }; - - /* reexec.c */ --- -2.43.0 - diff --git a/SOURCES/0003-vddk-do_extents-Mark-some-local-variables-const.patch b/SOURCES/0003-vddk-do_extents-Mark-some-local-variables-const.patch deleted file mode 100644 index f775fd2..0000000 --- a/SOURCES/0003-vddk-do_extents-Mark-some-local-variables-const.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dff3fc3b97aab79f6ee168a9b9dd2dff05425439 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 6 Jan 2025 15:37:54 +0000 -Subject: [PATCH] vddk: do_extents: Mark some local variables const - -These are never changed in the code (they are fields copied out from -the *cmd struct), so mark them as const. - -Acked-by: Eric Blake -(cherry picked from commit 24fd7df460ae31fe3f72b5100ca3dbe138bbadbe) ---- - plugins/vddk/worker.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -index 5982fcea..bc015d16 100644 ---- a/plugins/vddk/worker.c -+++ b/plugins/vddk/worker.c -@@ -388,9 +388,9 @@ add_extent (struct nbdkit_extents *extents, - static int - do_extents (struct command *cmd, struct vddk_handle *h) - { -- uint32_t count = cmd->count; -- uint64_t offset = cmd->offset; -- bool req_one = cmd->req_one; -+ const uint32_t count = cmd->count; -+ const uint64_t offset = cmd->offset; -+ const bool req_one = cmd->req_one; - struct nbdkit_extents *extents = cmd->ptr; - uint64_t position, end, start_sector; - --- -2.43.0 - diff --git a/SOURCES/0004-vddk-do_extents-Exit-the-function-if-we-hit-req_one-.patch b/SOURCES/0004-vddk-do_extents-Exit-the-function-if-we-hit-req_one-.patch deleted file mode 100644 index 5a64404..0000000 --- a/SOURCES/0004-vddk-do_extents-Exit-the-function-if-we-hit-req_one-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 5f7e5399aa4b208cb6aa0c51dbea59f73fd4d5f3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 6 Jan 2025 16:39:51 +0000 -Subject: [PATCH] vddk: do_extents: Exit the function if we hit req_one - condition - -No change to the functionality, since the code previously called -'return 0' immediately following the loop. - -Acked-by: Eric Blake -(cherry picked from commit 2f4d71f8f704d89d69cd635791c3239d2f44d631) ---- - plugins/vddk/worker.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -index bc015d16..112111e3 100644 ---- a/plugins/vddk/worker.c -+++ b/plugins/vddk/worker.c -@@ -471,7 +471,7 @@ do_extents (struct command *cmd, struct vddk_handle *h) - * overlapping the original offset we're done. - */ - if (req_one && position > offset) -- break; -+ return 0; - } - - return 0; --- -2.43.0 - diff --git a/SOURCES/0005-vddk-do_extents-Avoid-reading-partial-chunk-beyond-t.patch b/SOURCES/0005-vddk-do_extents-Avoid-reading-partial-chunk-beyond-t.patch deleted file mode 100644 index 8d293f5..0000000 --- a/SOURCES/0005-vddk-do_extents-Avoid-reading-partial-chunk-beyond-t.patch +++ /dev/null @@ -1,202 +0,0 @@ -From fe65a789da92e53bfd3f3814f1c93566f69591db Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 6 Jan 2025 15:45:35 +0000 -Subject: [PATCH] vddk: do_extents: Avoid reading partial chunk beyond the end - of the disk - -The QueryAllocatedBlocks API has (another) frustrating feature. It -can only query whole "chunks" (128 sectors). If the disk size is not -aligned to the chunk size (say the size was 129 sectors) then there's -a bit at the end which cannot be queried. Furthermore, the API gives -an error in this case instead of being helpful: - - VixDiskLib_QueryAllocatedBlocks: One of the parameters was invalid - -Fixes: https://issues.redhat.com/browse/RHEL-71694 -Reported-by: Ming Xie -Acked-by: Eric Blake -(cherry picked from commit fd918f3d1a185fd996999766c75acb9d6e22395d) ---- - plugins/vddk/worker.c | 29 ++++++++- - tests/Makefile.am | 5 +- - tests/test-vddk-real-unaligned-chunk.sh | 82 +++++++++++++++++++++++++ - 3 files changed, 113 insertions(+), 3 deletions(-) - create mode 100755 tests/test-vddk-real-unaligned-chunk.sh - -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -index 112111e3..8a91250a 100644 ---- a/plugins/vddk/worker.c -+++ b/plugins/vddk/worker.c -@@ -392,10 +392,9 @@ do_extents (struct command *cmd, struct vddk_handle *h) - const uint64_t offset = cmd->offset; - const bool req_one = cmd->req_one; - struct nbdkit_extents *extents = cmd->ptr; -- uint64_t position, end, start_sector; -+ uint64_t position, start_sector, size_sectors, last_queryable_sector, end; - - position = offset; -- end = offset + count; - - /* We can only query whole chunks. Therefore start with the - * first chunk before offset. -@@ -403,6 +402,21 @@ do_extents (struct command *cmd, struct vddk_handle *h) - start_sector = - ROUND_DOWN (offset, VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE) - / VIXDISKLIB_SECTOR_SIZE; -+ -+ /* Calculate the end byte + 1 that we're going to query, normally -+ * this is offset + count. -+ * -+ * However since chunks are larger than sectors, for a disk which -+ * has size which is not aligned to the chunk size there is a part -+ * of the disk at the end that we can never query. Reduce 'end' to -+ * the maximum possible queryable part of the disk, and we'll deal -+ * with the unaligned bit after the loop (RHEL-71694). -+ */ -+ end = offset + count; -+ size_sectors = h->size / VIXDISKLIB_SECTOR_SIZE; -+ last_queryable_sector = ROUND_DOWN (size_sectors, VIXDISKLIB_MIN_CHUNK_SIZE); -+ end = MIN (end, last_queryable_sector * VIXDISKLIB_SECTOR_SIZE); -+ - while (start_sector * VIXDISKLIB_SECTOR_SIZE < end) { - VixError err; - uint32_t i; -@@ -474,6 +488,17 @@ do_extents (struct command *cmd, struct vddk_handle *h) - return 0; - } - -+ /* If 'end' spanned beyond the last chunk of the disk, then we -+ * reduced it above to avoid reading a chunk that extends beyond the -+ * end of the underlying disk. We have to synthesize an allocated -+ * block here, which is what VDDK's example code does -+ * (doc/samples/diskLib/vixDiskLibSample.cpp: DoGetAllocatedBlocks). -+ */ -+ if (end < offset + count) { -+ if (add_extent (extents, &position, offset + count, false) == -1) -+ return -1; -+ } -+ - return 0; - } - -diff --git a/tests/Makefile.am b/tests/Makefile.am -index c0d1bdcc..94d4a219 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -188,7 +188,8 @@ if HAVE_VDDK - check-vddk: - $(MAKE) check TESTS="test-vddk-real.sh \ - test-vddk-real-dump-plugin.sh \ -- test-vddk-real-create.sh" -+ test-vddk-real-create.sh \ -+ test-vddk-real-unaligned-chunk.sh" - endif HAVE_VDDK - - #---------------------------------------------------------------------- -@@ -1172,6 +1173,7 @@ TESTS += \ - test-vddk-password-interactive.sh \ - test-vddk-real-create.sh \ - test-vddk-real-dump-plugin.sh \ -+ test-vddk-real-unaligned-chunk.sh \ - test-vddk-real.sh \ - test-vddk-reexec.sh \ - test-vddk-run.sh \ -@@ -1204,6 +1206,7 @@ EXTRA_DIST += \ - test-vddk-password-interactive.sh \ - test-vddk-real-create.sh \ - test-vddk-real-dump-plugin.sh \ -+ test-vddk-real-unaligned-chunk.sh \ - test-vddk-real.sh \ - test-vddk-reexec.sh \ - test-vddk-run.sh \ -diff --git a/tests/test-vddk-real-unaligned-chunk.sh b/tests/test-vddk-real-unaligned-chunk.sh -new file mode 100755 -index 00000000..28fccd6c ---- /dev/null -+++ b/tests/test-vddk-real-unaligned-chunk.sh -@@ -0,0 +1,82 @@ -+#!/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. -+ -+# Regression test for https://issues.redhat.com/browse/RHEL-71694 -+ -+source ./functions.sh -+set -e -+set -x -+ -+requires_run -+requires test "x$vddkdir" != "x" -+requires test -d "$vddkdir" -+requires test -f "$vddkdir/lib64/libvixDiskLib.so" -+requires qemu-img --version -+requires_nbdinfo -+requires $TRUNCATE --version -+requires dd --version -+requires test -r /dev/urandom -+skip_if_valgrind "because setting LD_LIBRARY_PATH breaks valgrind" -+ -+# VDDK > 5.1.1 only supports x86_64. -+if [ `uname -m` != "x86_64" ]; then -+ echo "$0: unsupported architecture" -+ exit 77 -+fi -+ -+d=vddk-real-unaligned-chunk.d -+cleanup_fn rm -rf $d -+rm -rf $d -+mkdir $d -+ -+# Create a vmdk disk which is partially sparse and the size is NOT -+# aligned to 128 sectors (chunk size). -+dd if=/dev/urandom of=$d/test.raw bs=512 count=$(( 3*128 )) -+$TRUNCATE -s $(( (4*128 + 3) * 512)) $d/test.raw -+qemu-img convert -f raw $d/test.raw -O vmdk $d/test.vmdk -+ -+# Read the map using VDDK. -+export d -+nbdkit -rfv vddk libdir="$vddkdir" \ -+ $PWD/$d/test.vmdk \ -+ --run 'nbdinfo --map "$uri" > $d/map' -+cat $d/map -+ -+# Note a few features of the expected map. The first 3 chunks (3*128 -+# sectors) are allocated, followed by a single hole chunk. Then the -+# last 3 unaligned sectors appear allocated (even though they are not) -+# because we could not read them using the QueryAllocatedBlocks API so -+# we had to assume allocated. -+test "$(cat $d/map)" = "\ -+ 0 196608 0 data -+ 196608 65536 3 hole,zero -+ 262144 1536 0 data" --- -2.43.0 - diff --git a/SOURCES/0006-server-Fix-.zero-fallback-path.patch b/SOURCES/0006-server-Fix-.zero-fallback-path.patch deleted file mode 100644 index e56985a..0000000 --- a/SOURCES/0006-server-Fix-.zero-fallback-path.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 254edc8b3b8d67a952919a32e7aea0e1e8c26b78 Mon Sep 17 00:00:00 2001 -From: Darren Archibald -Date: Wed, 6 Aug 2025 03:29:39 -0700 -Subject: [PATCH] server: Fix .zero fallback path - -When no efficient zero method is supported, we fall back to writing a -buffer of actual zeroes. However because of an omitted update to -'offset' we would only zero out (up to) the first 64M of each range. -nbdcopy defaults to working on blocks of 128M, leaving the second 64M -unzeroed. - -This affects only backing filesystems which do not support fallocate -FALLOC_FL_PUNCH_HOLE or FALLOC_FL_ZERO_RANGE, which turns out to be -rare, but it does include some NFS-mounted filesystems which is where -I saw this problem. - -Fixes: commit 19184d3 -Thanks: Alex Kalenyuk - -Signed-off-by: Darren Archibald ---- - server/plugins.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/server/plugins.c b/server/plugins.c -index 3c7df0d..db36ce4 100644 ---- a/server/plugins.c -+++ b/server/plugins.c -@@ -807,6 +807,7 @@ plugin_zero (struct context *c, - if (r == -1) - break; - count -= limit; -+ offset += limit; - } - - done: --- -2.31.1 - diff --git a/SOURCES/nbdkit-1.40.4.tar.gz.sig b/SOURCES/nbdkit-1.40.4.tar.gz.sig deleted file mode 100644 index 9b3bb61..0000000 --- a/SOURCES/nbdkit-1.40.4.tar.gz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmb3G0QRHHJpY2hAYW5u -ZXhpYS5vcmcACgkQkXOPc+G3aKBAohAAmJ03Ebg70A6EiKf2HCI1rLC5emLCzwX+ -6YihoD7lFoYh8LPNfg7WCfG8WlrHS3kgb7zIRaqVYn5HWWs/vNAU2+R8uoHoRETe -hvAZZuXKxDkgNM5CYT7G6sGXQnh5Gn/XNo45oypHFh/vupkjEj5KtgRHkBFivut9 -/fe9JC2IW22FhyuK3XD0zf4tI2m78bLdE4S/tyWuHSGks1cJy5oq03qOkOwFUNOb -xPvMkPepLClxmgr5fWuKt2A4K/EgrnBOtEvT+lAfI70J12Yiz19VdKK4AV3kBfOm -U9LrDa6jOCtEkO9leiWUl7LguzyqCsI8r/72OC+Ub/RIIqDqh7tQi7ZwcdvJCZb7 -ZtIY43/XeqFtLXh8D//FpcBwdu9O8h81aTH2s/5QaIUPoY3jCTY+3r5ENv1793YB -Ar6uWRXt6ID4TaFWO9gPJ4+J0qJJwK39K1CmvA72xn2wBTzoZMp1DEt8Jh/Dnnnp -74yqhisWXN4ZH+sXKhmSuDl37B0zjRtrGQltTEdcSykh2Gr92f89v87FcUh9PFrj -cq+hjzoYNQWsjutgKEuqwSM1wmeFOok81fKfwAFqqt+damw7vSUyCXDidh8FDgHC -l2EwibvKWAQzB+ywqRxP0cekhqqY2WEqW0JFNMLMvJRFOdwooSjB03kwTMQj7/42 -01UYnKoT2u4= -=7H2+ ------END PGP SIGNATURE----- diff --git a/SOURCES/copy-patches.sh b/copy-patches.sh old mode 100755 new mode 100644 similarity index 98% rename from SOURCES/copy-patches.sh rename to copy-patches.sh index cfa8a5b..5dc5564 --- a/SOURCES/copy-patches.sh +++ b/copy-patches.sh @@ -6,7 +6,7 @@ set -e # directory. Use it like this: # ./copy-patches.sh -rhel_version=10.0 +rhel_version=10.1 # Check we're in the right directory. if [ ! -f nbdkit.spec ]; then diff --git a/nbdkit-1.44.1.tar.gz.sig b/nbdkit-1.44.1.tar.gz.sig new file mode 100644 index 0000000..66a42bd --- /dev/null +++ b/nbdkit-1.44.1.tar.gz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJFBAABCgAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmho1AYRHHJpY2hAYW5u +ZXhpYS5vcmcACgkQkXOPc+G3aKCFIg/9GJF0Ok1j2FXx7rZEanLv4lJveFi0rYQD +z3BXRX4JuaiCPLzvWiABqBN9P0h8WzhdE3ir50gG1a03+q9AfRbyVGu/LCnakVUv +58h/SE36sK4K1Gptp+cZbbjb7kwMNXl/c158YChOAW4St35zYELW79Vf9+rjj7Nz +S3ppKMCE1lkBmd3R5+AUN962yz2BPF9K1CTBLJZD89nwsPw5e5A0RvRedxEvgxYD +lMT/6DgxhPFpywqpv6NxN/Qq/vHGT0EtuAco3+Iqp5LX/sPBxPWNUGK+zZn5T8dp +ss/s8uC8YIGwlPtGNUm25lS5hbA9l3D8RTtk/fL7BJB/92z3BEx8H0F0H2PokG9Z +9FEmqaYglZM7Z4fdpJxkBjXN6UFOsu0nUR6EnIZKHnU/HtzmgXLsjrEPtxem/jqe +iYgLL2ykpRrRLdZIvG1SpyTGLtJqgEGquo+3OWj1FfzFf93a2x1KoIdatBVCYzM5 +5JCE42RolpOsRJQ0t297zM93H6njz7irrvpFiVlYIUbVr3+tzAe77F/PBTnBapUe +Dxcy61t5PWWLGwAsFtxb8Q6Vx1ssnCpn+8wqslBJWcIWrKtn8GF5dTrGUvvilwkH +66VcLXGaNbyOq5jyS4gpMdZWw1GLmyujQB8hoyOc9+n6tLe3hHEYuTTT2pY/jLk2 +EYCKR70jPIQ= +=XzGJ +-----END PGP SIGNATURE----- diff --git a/SOURCES/nbdkit-find-provides b/nbdkit-find-provides old mode 100755 new mode 100644 similarity index 100% rename from SOURCES/nbdkit-find-provides rename to nbdkit-find-provides diff --git a/SOURCES/nbdkit.attr b/nbdkit.attr similarity index 100% rename from SOURCES/nbdkit.attr rename to nbdkit.attr diff --git a/SOURCES/nbdkit.fc b/nbdkit.fc similarity index 100% rename from SOURCES/nbdkit.fc rename to nbdkit.fc diff --git a/SOURCES/nbdkit.if b/nbdkit.if similarity index 100% rename from SOURCES/nbdkit.if rename to nbdkit.if diff --git a/SPECS/nbdkit.spec b/nbdkit.spec similarity index 95% rename from SPECS/nbdkit.spec rename to nbdkit.spec index eb2b81b..df87f67 100644 --- a/SPECS/nbdkit.spec +++ b/nbdkit.spec @@ -51,10 +51,10 @@ %global verify_tarball_signature 1 # The source directory. -%global source_directory 1.40-stable +%global source_directory 1.44-stable Name: nbdkit -Version: 1.40.4 +Version: 1.44.1 Release: 4%{?dist} Summary: NBD server @@ -77,15 +77,20 @@ Source2: libguestfs.keyring Source3: copy-patches.sh # Patches come from the upstream repository: -# https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-10.0/ +# https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-10.1/ # Patches. -Patch0001: 0001-vddk-Include-stdbool.h.patch -Patch0002: 0002-vddk-Cache-the-disk-size-in-the-handle.patch -Patch0003: 0003-vddk-do_extents-Mark-some-local-variables-const.patch -Patch0004: 0004-vddk-do_extents-Exit-the-function-if-we-hit-req_one-.patch -Patch0005: 0005-vddk-do_extents-Avoid-reading-partial-chunk-beyond-t.patch -Patch0006: 0006-server-Fix-.zero-fallback-path.patch +Patch0001: 0001-common-Add-ONCE-macro-to-run-code-only-once.patch +Patch0002: 0002-file-zero-Print-the-debug-message-on-the-fallback-pa.patch +Patch0003: 0003-file-trim-Don-t-try-BLKDISCARD-if-earlier-FALLOC_FL_.patch +Patch0004: 0004-common-include-test-once.c-Skip-test-on-macOS-which-.patch +Patch0005: 0005-common-include-test-once.c-Further-fixes-for-pthread.patch +Patch0006: 0006-Remove-deprecated-cacheextents-filter.patch +Patch0007: 0007-New-filter-nbdkit-count-filter-count-bytes-read-writ.patch +Patch0008: 0008-count-Clarify-documentation.patch +Patch0009: 0009-vddk-Don-t-use-FNM_PATHNAME-when-matching-export-par.patch +Patch0010: 0010-file-Don-t-advertise-minimum_io_size-64K-the-max-sup.patch +Patch0011: 0011-file-Change-calculations-of-block-size-hints-for-blo.patch # For automatic RPM Provides generation. # See: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html @@ -104,6 +109,7 @@ BuildRequires: git BuildRequires: autoconf, automake, libtool BuildRequires: make +BuildRequires: libxcrypt-devel BuildRequires: gcc, gcc-c++ BuildRequires: %{_bindir}/pod2man BuildRequires: pkgconfig(gnutls) @@ -121,6 +127,10 @@ BuildRequires: pkgconfig(bzip2) BuildRequires: pkgconfig(libzstd) BuildRequires: pkgconfig(libcurl) BuildRequires: pkgconfig(libnbd) +%if !0%{?rhel} +# We require libnfs >= 6, but the internal version is >= 16 +BuildRequires: pkgconfig(libnfs) >= 16 +%endif BuildRequires: pkgconfig(libssh) BuildRequires: e2fsprogs BuildRequires: pkgconfig(ext2fs) @@ -169,6 +179,9 @@ BuildRequires: glibc-utils BuildRequires: /usr/bin/hexdump BuildRequires: /usr/sbin/ip BuildRequires: jq +%if !0%{?rhel} +BuildRequires: /usr/bin/lzip +%endif BuildRequires: /usr/bin/nbdcopy BuildRequires: /usr/bin/nbdinfo BuildRequires: /usr/bin/nbdsh @@ -287,8 +300,6 @@ nbdkit-info-plugin Serve client and server information. nbdkit-memory-plugin A virtual memory plugin. -nbdkit-ondemand-plugin Create filesystems on demand. - nbdkit-ones-plugin Fill disk with repeated 0xff or other bytes. nbdkit-pattern-plugin Fixed test pattern. @@ -444,6 +455,16 @@ This package lets you forward NBD connections from %{name} to another NBD server. +%if !0%{?rhel} +%package nfs-plugin +Summary: NFS (Network File Server) plugin for %{name} +Requires: %{name}-server%{?_isa} = %{version}-%{release} + +%description nfs-plugin +This package contains Network File Server (NFS) support for %{name}. +%endif + + %if !0%{?rhel} && 0%{?have_ocaml} %package ocaml-plugin Summary: OCaml plugin for %{name} @@ -466,6 +487,21 @@ This package lets you write OCaml plugins for %{name}. %endif +%package ondemand-plugin +Summary: Create filesystems on demand for %{name} +Requires: %{name}-server%{?_isa} = %{version}-%{release} +# For mkfs and mke2fs (defaults). +Requires: util-linux, e2fsprogs +# For other filesystems. +Suggests: xfsprogs +%if !0%{?rhel} +Suggests: ntfsprogs, dosfstools +%endif + +%description ondemand-plugin +This package is a plugin to create filesystems on demand for %{name}. + + %if !0%{?rhel} %package perl-plugin Summary: Perl plugin for %{name} @@ -548,7 +584,7 @@ This package is a BitTorrent plugin for %{name}. Summary: VMware VDDK plugin for %{name} Requires: %{name}-server%{?_isa} = %{version}-%{release} # https://bugzilla.redhat.com/show_bug.cgi?id=1931818 -Requires: libxcrypt-compat +Requires: libxcrypt-compat%{?_isa} %description vddk-plugin This package is a plugin for %{name} which connects to @@ -573,10 +609,10 @@ nbdkit-blocksize-policy-filter Set block size constraints and policy. nbdkit-cache-filter Server-side cache. -nbdkit-cacheextents-filter Cache extents. - nbdkit-checkwrite-filter Check writes match contents of plugin. +nbdkit-count-filter Count bytes read, written, zeroed and trimmed. + nbdkit-cow-filter Copy-on-write overlay for read-only plugins. nbdkit-ddrescue-filter Filter for serving from ddrescue dump. @@ -621,6 +657,8 @@ nbdkit-nozero-filter Adjust handling of zero requests by plugins. nbdkit-offset-filter Serve an offset and range. +nbdkit-openonce-filter Open the underlying plugin once. + nbdkit-partition-filter Serve a single partition. nbdkit-pause-filter Pause NBD requests. @@ -649,6 +687,8 @@ nbdkit-spinning-filter Add seek delays to simulate a spinning hard disk. nbdkit-swab-filter Filter for swapping byte order. +nbdkit-time-limit-filter Set an overall time limit for each connection. + nbdkit-tls-fallback-filter TLS protection filter. nbdkit-truncate-filter Truncate, expand, round up or round down size. @@ -691,11 +731,11 @@ This package is a tar archive filter for %{name}. %package xz-filter -Summary: XZ filter for %{name} +Summary: XZ and lzip filters for %{name} Requires: %{name}-server%{?_isa} = %{version}-%{release} %description xz-filter -This package is the xz filter for %{name}. +This package contains the xz and lzip filters for %{name}. %package devel @@ -739,7 +779,7 @@ BuildRequires: selinux-policy-devel %{?selinux_requires} %description selinux -%{nbdkit} SELinux policy module. +%{name} SELinux policy module. %endif @@ -885,10 +925,7 @@ bzip2 -9 %{modulename}.pp popd %if 0%{?have_mingw} -# MC=no is a temporary hack until this bug is fixed in binutils: -# https://sourceware.org/bugzilla/show_bug.cgi?id=31283 %mingw_configure \ - MC=no \ --disable-static \ --enable-shared \ --with-extra='%{name}-%{version}-%{release}' \ @@ -1090,7 +1127,6 @@ fi %{_libdir}/%{name}/plugins/nbdkit-full-plugin.so %{_libdir}/%{name}/plugins/nbdkit-info-plugin.so %{_libdir}/%{name}/plugins/nbdkit-memory-plugin.so -%{_libdir}/%{name}/plugins/nbdkit-ondemand-plugin.so %{_libdir}/%{name}/plugins/nbdkit-ones-plugin.so %{_libdir}/%{name}/plugins/nbdkit-partitioning-plugin.so %{_libdir}/%{name}/plugins/nbdkit-pattern-plugin.so @@ -1106,7 +1142,6 @@ fi %{_mandir}/man1/nbdkit-full-plugin.1* %{_mandir}/man1/nbdkit-info-plugin.1* %{_mandir}/man1/nbdkit-memory-plugin.1* -%{_mandir}/man1/nbdkit-ondemand-plugin.1* %{_mandir}/man1/nbdkit-ones-plugin.1* %{_mandir}/man1/nbdkit-partitioning-plugin.1* %{_mandir}/man1/nbdkit-pattern-plugin.1* @@ -1220,6 +1255,15 @@ fi %{_mandir}/man1/nbdkit-nbd-plugin.1* +%if !0%{?rhel} +%files nfs-plugin +%doc README.md +%license LICENSE +%{_libdir}/%{name}/plugins/nbdkit-nfs-plugin.so +%{_mandir}/man1/nbdkit-nfs-plugin.1* +%endif + + %if !0%{?rhel} && 0%{?have_ocaml} %files ocaml-plugin %doc README.md @@ -1234,6 +1278,13 @@ fi %endif +%files ondemand-plugin +%doc README.md +%license LICENSE +%{_libdir}/%{name}/plugins/nbdkit-ondemand-plugin.so +%{_mandir}/man1/nbdkit-ondemand-plugin.1* + + %if !0%{?rhel} %files perl-plugin %doc README.md @@ -1306,8 +1357,8 @@ fi %{_libdir}/%{name}/filters/nbdkit-blocksize-filter.so %{_libdir}/%{name}/filters/nbdkit-blocksize-policy-filter.so %{_libdir}/%{name}/filters/nbdkit-cache-filter.so -%{_libdir}/%{name}/filters/nbdkit-cacheextents-filter.so %{_libdir}/%{name}/filters/nbdkit-checkwrite-filter.so +%{_libdir}/%{name}/filters/nbdkit-count-filter.so %{_libdir}/%{name}/filters/nbdkit-cow-filter.so %{_libdir}/%{name}/filters/nbdkit-ddrescue-filter.so %{_libdir}/%{name}/filters/nbdkit-delay-filter.so @@ -1330,6 +1381,7 @@ fi %{_libdir}/%{name}/filters/nbdkit-noparallel-filter.so %{_libdir}/%{name}/filters/nbdkit-nozero-filter.so %{_libdir}/%{name}/filters/nbdkit-offset-filter.so +%{_libdir}/%{name}/filters/nbdkit-openonce-filter.so %{_libdir}/%{name}/filters/nbdkit-partition-filter.so %{_libdir}/%{name}/filters/nbdkit-pause-filter.so %{_libdir}/%{name}/filters/nbdkit-protect-filter.so @@ -1345,13 +1397,14 @@ fi %{_libdir}/%{name}/filters/nbdkit-scan-filter.so %{_libdir}/%{name}/filters/nbdkit-spinning-filter.so %{_libdir}/%{name}/filters/nbdkit-swab-filter.so +%{_libdir}/%{name}/filters/nbdkit-time-limit-filter.so %{_libdir}/%{name}/filters/nbdkit-tls-fallback-filter.so %{_libdir}/%{name}/filters/nbdkit-truncate-filter.so %{_mandir}/man1/nbdkit-blocksize-filter.1* %{_mandir}/man1/nbdkit-blocksize-policy-filter.1* %{_mandir}/man1/nbdkit-cache-filter.1* -%{_mandir}/man1/nbdkit-cacheextents-filter.1* %{_mandir}/man1/nbdkit-checkwrite-filter.1* +%{_mandir}/man1/nbdkit-count-filter.1* %{_mandir}/man1/nbdkit-cow-filter.1* %{_mandir}/man1/nbdkit-ddrescue-filter.1* %{_mandir}/man1/nbdkit-delay-filter.1* @@ -1374,6 +1427,7 @@ fi %{_mandir}/man1/nbdkit-noparallel-filter.1* %{_mandir}/man1/nbdkit-nozero-filter.1* %{_mandir}/man1/nbdkit-offset-filter.1* +%{_mandir}/man1/nbdkit-openonce-filter.1* %{_mandir}/man1/nbdkit-partition-filter.1* %{_mandir}/man1/nbdkit-pause-filter.1* %{_mandir}/man1/nbdkit-protect-filter.1* @@ -1389,6 +1443,7 @@ fi %{_mandir}/man1/nbdkit-scan-filter.1* %{_mandir}/man1/nbdkit-spinning-filter.1* %{_mandir}/man1/nbdkit-swab-filter.1* +%{_mandir}/man1/nbdkit-time-limit-filter.1* %{_mandir}/man1/nbdkit-tls-fallback-filter.1* %{_mandir}/man1/nbdkit-truncate-filter.1* @@ -1426,7 +1481,9 @@ fi %files xz-filter %doc README.md %license LICENSE +%{_libdir}/%{name}/filters/nbdkit-lzip-filter.so %{_libdir}/%{name}/filters/nbdkit-xz-filter.so +%{_mandir}/man1/nbdkit-lzip-filter.1* %{_mandir}/man1/nbdkit-xz-filter.1* @@ -1459,6 +1516,7 @@ fi %{_mandir}/man3/nbdkit-plugin.3* %{_mandir}/man3/nbdkit_*.3* %{_mandir}/man1/nbdkit-release-notes-1.*.1* +%{_mandir}/man3/nbdkit-tracing.3* %{_libdir}/pkgconfig/nbdkit.pc @@ -1503,9 +1561,40 @@ fi %changelog -* Wed Aug 06 2025 Darren Archibald - 1.40.4-4 +* Mon Jan 12 2026 Richard W.M. Jones - 1.44.1-4 +- Fix v2v conversion failure when minimum_io_size > 64K + resolves: RHEL-140707 + +* Tue Jan 06 2026 Richard W.M. Jones - 1.44.1-3 +- vddk export parameter should allow loose wildcards without FNM_PATHNAME + resolves: RHEL-137303 + +* Wed Jul 09 2025 Richard W.M. Jones - 1.44.1-2 +- Rebase to nbdkit 1.44.1 + resolves: RHEL-78830, RHEL-101180 +- Synch the spec file with Fedora Rawhide. +- nbdkit-ondemand-plugin moves into a new subpackage. +- New nbdkit-count-filter & nbdkit-time-limit-filter. +- Remove nbdkit-cacheextents-filter. +- Add extra system call checking and debugging to nbdkit-file-plugin + resolves: RHEL-85515 +- Allow nbdkit-file-plugin to zero and trim block devices + resolves: RHEL-89371 +- vddk: Pre-cache the extents for readonly connections + resolves: RHEL-94825 +- Log filename, offset and count in nbdkit-file-plugin error messages + resolves: RHEL-95364 +- vddk: Improve statistics + related: RHEL-94825 +- CVE-2025-47711 denial of service attack by client sending maximum size block + status +- CVE-2025-47712 denial of service attack by client sending large unaligned + size block status + resolves: RHEL-95819 +- Add support for VDDK 9.0.0.0 + resolves: RHEL-99467 - server: Fix .zero fallback path - resolves: RHEL-101701 + resolves: RHEL-101636 * Mon Jan 06 2025 Richard W.M. Jones - 1.40.4-3 - vddk: Avoid reading partial chunk beyond the end of the disk diff --git a/SOURCES/nbdkit.te b/nbdkit.te similarity index 100% rename from SOURCES/nbdkit.te rename to nbdkit.te diff --git a/sources b/sources new file mode 100644 index 0000000..0df5130 --- /dev/null +++ b/sources @@ -0,0 +1,2 @@ +SHA512 (libguestfs.keyring) = 69663d5dd3edb47af6f18119c0748211c1cecf230c2dd8baaf349f44df1f893730ca6bb8b1f60a55ea42f8ff04fd48c3e5954501bb57952950032012a42c9f19 +SHA512 (nbdkit-1.44.1.tar.gz) = 150a31ca7f64b76a4e4cc90d077e88531458f2766c0bb1f6f1ae23176d5c55a2e4dab61be58bd92b166e67fe70b67c9458a04d29978cbb1b89a6fa8ebca4617d