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