import CS libnbd-1.20.3-4.el9

This commit is contained in:
eabdullin 2025-09-15 12:15:13 +00:00
parent 1865b024f0
commit 7fac711599
14 changed files with 1459 additions and 7 deletions

View File

@ -187,5 +187,5 @@ index 45893a8b..6c7cc45c 100644
return 0;
}
--
2.43.0
2.47.1

View File

@ -34,5 +34,5 @@ index 600265a0..5872dd54 100644
}
return r;
--
2.43.0
2.47.1

View File

@ -39,5 +39,5 @@ index 3945411e..699e24aa 100644
nbd_internal_free_option (h);
SET_NEXT_STATE (%.NEGOTIATING);
--
2.43.0
2.47.1

View File

@ -171,5 +171,5 @@ index 6c7cc45c..8c483bd2 100644
return 0;
}
--
2.43.0
2.47.1

View File

@ -23,5 +23,5 @@ index 8c483bd2..1e026a8a 100644
fprintf (fp, ": ");
for (i = 0; i < replylen; ++i) {
--
2.43.0
2.47.1

View File

@ -0,0 +1,49 @@
From 1c9d65c6100edfd6050b34dcf29a7a1bbdf5e89a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 29 Mar 2025 14:00:39 +0000
Subject: [PATCH] copy: Set the total size in bytes copied
Ensure that src->size contains the total size in bytes copied. There
is (only) one place where this is not known in advance, which is when
we are reading from a pipe.
(cherry picked from commit afe4f390a65a0d1b9f3625bf90c73726866e0a64)
---
copy/main.c | 3 +++
copy/synch-copying.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/copy/main.c b/copy/main.c
index ae9840ae..cd7b2fd2 100644
--- a/copy/main.c
+++ b/copy/main.c
@@ -479,6 +479,9 @@ main (int argc, char *argv[])
/* Always set the progress bar to 100% at the end of the copy. */
progress_bar (1, 1);
+ /* We should always know the total size copied here. */
+ assert (src->size >= 0);
+
/* Shut down the source side. */
src->ops->close (src);
diff --git a/copy/synch-copying.c b/copy/synch-copying.c
index 2f6627bf..200c97f6 100644
--- a/copy/synch-copying.c
+++ b/copy/synch-copying.c
@@ -53,6 +53,12 @@ synch_copying (void)
offset += r;
progress_bar (offset, src->size);
}
+
+ /* Record the total amount of data that was copied. In all other
+ * cases, src->size will already be set to the true size, so here
+ * is the only place we have to set this.
+ */
+ src->size = offset;
}
/* Otherwise we know how much we're copying, so we can copy in whole
--
2.47.1

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@
Name: libnbd
Version: 1.20.3
Release: 1%{?dist}
Release: 4%{?dist}
Summary: NBD client library in userspace
License: LGPL-2.0-or-later AND BSD-3-Clause
@ -46,6 +46,13 @@ Patch0002: 0002-lib-Don-t-overwrite-error-in-nbd_opt_-go-info.patch
Patch0003: 0003-generator-Restore-assignment-to-local-err.patch
Patch0004: 0004-generator-states-newstyle.c-Quote-untrusted-string-f.patch
Patch0005: 0005-generator-states-newstyle.c-Don-t-sign-extend-escape.patch
Patch0006: 0006-copy-Set-the-total-size-in-bytes-copied.patch
Patch0007: 0007-copy-Add-blkhash-option.patch
Patch0008: 0008-copy-Fix-crash-when-blkhash-size-is-not-a-power-of-2.patch
Patch0009: 0009-copy-Define-block_type-outside-of-block-struct.patch
Patch0010: 0010-copy-Shrink-struct-block.patch
Patch0011: 0011-copy-Enable-zero-optimization-for-allocated-extents.patch
Patch0012: 0012-copy-Fix-corrupted-hash-on-incomplete-read.patch
%if 0%{verify_tarball_signature}
BuildRequires: gnupg2
@ -390,6 +397,10 @@ make %{?_smp_mflags} check || {
%changelog
* Tue Apr 15 2025 Richard W.M. Jones <rjones@redhat.com> - 1.20.3-4
- Add nbdcopy --blkhash option
resolves: RHEL-85509
* Sat Sep 28 2024 Richard W.M. Jones <rjones@redhat.com> - 1.20.3-1
- Rebase to libnbd 1.20.3