Merge tag 'pull-nbd-2025-05-29' of https://repo.or.cz/qemu/ericb into staging

NBD patches for 2025-05-29

- Nir Soffer: Allow for larger Unix socket buffers in NBD
- Eric Blake: clean up mirror-sparse iotest issues

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEEccLMIrHEYCkn0vOqp6FrSiUnQ2oFAmg42T0ACgkQp6FrSiUn
# Q2r5nwgAg4ftfPBnynqL54dQ6rPKPOwW3n4Ei26EsC86OcFIGEGuCK6UGBH4bH6d
# BgyjNWY/6/t90vnXcBGVFmxrugHGh3TwOpAY08TqW0LGmpJiwX5wZTk3cVbcwXat
# ME8oYeOQwLwqboFthlgnXsUuQrKtXrkY27154ztH354x4bi5AmHi//Or4+EdFf8L
# /cCmS7uHPiHV9l1+U1hV4i1UQ+3rWHIOcfn/sKeEwPfrlyEW+2fxWUjl7qyf/Mqz
# EwCtkjz4WsFTxYyQPN6r3NyoEIZDRK27srubVhat6Fk9gOnR5Rh2MCntyxUpXmo5
# 4xD3QkVbXVRhXv6n6rjmA/Q3bvZ1oQ==
# =yjPj
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 29 May 2025 18:01:33 EDT
# gpg:                using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full]
# gpg:                 aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full]
# gpg:                 aka "[jpeg image of size 6874]" [full]
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2  F3AA A7A1 6B4A 2527 436A

* tag 'pull-nbd-2025-05-29' of https://repo.or.cz/qemu/ericb:
  iotests: Filter out ZFS in several tests
  iotests: Improve mirror-sparse on ext4 and xfs
  iotests: Use disk_usage in more places
  nbd: Set unix socket send buffer on Linux
  nbd: Set unix socket send buffer on macOS
  io: Add helper for setting socket send buffer size

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2025-05-30 11:40:56 -04:00
15 changed files with 105 additions and 6 deletions
+13
View File
@@ -261,5 +261,18 @@ QIOChannelSocket *
qio_channel_socket_accept(QIOChannelSocket *ioc,
Error **errp);
/**
* qio_channel_socket_set_send_buffer:
* @ioc: the socket channel object
* @size: buffer size
* @errp: pointer to a NULL-initialized error object
*
* Set the underlying socket send buffer size.
*
* Retruns: 0 on success, or -1 on error.
*/
int qio_channel_socket_set_send_buffer(QIOChannelSocket *ioc,
size_t size,
Error **errp);
#endif /* QIO_CHANNEL_SOCKET_H */
+11
View File
@@ -78,6 +78,17 @@ qio_channel_socket_new(void)
return sioc;
}
int qio_channel_socket_set_send_buffer(QIOChannelSocket *ioc,
size_t size,
Error **errp)
{
if (setsockopt(ioc->fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) {
error_setg_errno(errp, errno, "Unable to set socket send buffer size");
return -1;
}
return 0;
}
static int
qio_channel_socket_set_fd(QIOChannelSocket *sioc,
+3
View File
@@ -31,6 +31,8 @@
#include "qapi/clone-visitor.h"
#include "qemu/coroutine.h"
#include "nbd/nbd-internal.h"
struct NBDClientConnection {
/* Initialization constants, never change */
SocketAddress *saddr; /* address to connect to */
@@ -140,6 +142,7 @@ static int nbd_connect(QIOChannelSocket *sioc, SocketAddress *addr,
return ret;
}
nbd_set_socket_send_buffer(sioc);
qio_channel_set_delay(QIO_CHANNEL(sioc), false);
if (!info) {
+26
View File
@@ -18,6 +18,9 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "io/channel-socket.h"
#include "qapi/error.h"
#include "qemu/units.h"
#include "nbd-internal.h"
/* Discard length bytes from channel. Return -errno on failure and 0 on
@@ -264,3 +267,26 @@ const char *nbd_mode_lookup(NBDMode mode)
return "<unknown>";
}
}
/*
* Testing shows that 2m send buffer is optimal. Changing the receive buffer
* size has no effect on performance.
* On Linux we need to increase net.core.wmem_max to make this effective.
*/
#if defined(__APPLE__) || defined(__linux__)
#define UNIX_STREAM_SOCKET_SEND_BUFFER_SIZE (2 * MiB)
#endif
void nbd_set_socket_send_buffer(QIOChannelSocket *sioc)
{
#ifdef UNIX_STREAM_SOCKET_SEND_BUFFER_SIZE
if (sioc->localAddr.ss_family == AF_UNIX) {
size_t size = UNIX_STREAM_SOCKET_SEND_BUFFER_SIZE;
Error *errp = NULL;
if (qio_channel_socket_set_send_buffer(sioc, size, &errp) < 0) {
warn_report_err(errp);
}
}
#endif /* UNIX_STREAM_SOCKET_SEND_BUFFER_SIZE */
}
+5
View File
@@ -74,4 +74,9 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size,
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
/* nbd_set_socket_send_buffer
* Set the socket send buffer size for optimal performance.
*/
void nbd_set_socket_send_buffer(QIOChannelSocket *sioc);
#endif
+2
View File
@@ -3291,6 +3291,8 @@ void nbd_client_new(QIOChannelSocket *sioc,
client->close_fn = close_fn;
client->owner = owner;
nbd_set_socket_send_buffer(sioc);
co = qemu_coroutine_create(nbd_co_client_start, client);
qemu_coroutine_enter(co);
}
+1
View File
@@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt raw
_supported_proto file fuse
_supported_os Linux
_require_disk_usage
# in kB
CREATION_SIZE=128
+1 -1
View File
@@ -35,7 +35,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
get_image_size_on_host()
{
echo $(($(stat -c '%b * %B' "$TEST_IMG_FILE")))
disk_usage "$TEST_IMG_FILE"
}
# get standard environment and filters
+1
View File
@@ -77,6 +77,7 @@ _supported_os Linux
_default_cache_mode none
_supported_cache_modes none directsync
_require_disk_usage
size=$((1 * 1024 * 1024))
+1
View File
@@ -41,6 +41,7 @@ _supported_os Linux
_default_cache_mode writeback
_supported_cache_modes writeback writethrough unsafe
_require_disk_usage
echo
echo "=== Check mapping of unaligned raw image ==="
+1
View File
@@ -41,6 +41,7 @@ _supported_os Linux
_default_cache_mode none
_supported_cache_modes none directsync
_require_disk_usage
echo
echo "=== Check mapping of unaligned raw image ==="
+3 -2
View File
@@ -51,6 +51,7 @@ _unsupported_fmt vpc
_supported_proto file # We create the FUSE export manually
_supported_os Linux # We need /dev/urandom
_require_disk_usage
# $1: Export ID
# $2: Options (beyond the node-name and ID)
@@ -290,7 +291,7 @@ echo '--- Try growing non-growable export ---'
# Get the current size so we can write beyond the EOF
orig_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
orig_disk_usage=$(stat -c '%b' "$TEST_IMG")
orig_disk_usage=$(disk_usage "$TEST_IMG")
# Should fail (exports are non-growable by default)
# (Note that qemu-io can never write beyond the EOF, so we have to use
@@ -312,7 +313,7 @@ else
echo 'OK: Post-truncate image size is as expected'
fi
new_disk_usage=$(stat -c '%b' "$TEST_IMG")
new_disk_usage=$(disk_usage "$TEST_IMG")
if [ "$new_disk_usage" -gt "$orig_disk_usage" ]; then
echo 'OK: Disk usage grew with fallocate'
else
+30
View File
@@ -996,6 +996,36 @@ _require_large_file()
rm "$FILENAME"
}
# Check whether disk_usage can be reliably used.
_require_disk_usage()
{
local unusable=false
# ZFS triggers known failures on this front; it does not immediately
# allocate files, and then aggressively compresses writes even when full
# allocation was requested.
if [ -z "$TEST_IMG_FILE" ]; then
FILENAME="$TEST_IMG"
else
FILENAME="$TEST_IMG_FILE"
fi
if [ -e "FILENAME" ]; then
echo "unwilling to overwrite existing file"
exit 1
fi
$QEMU_IMG create -f raw "$FILENAME" 5M > /dev/null
if [ $(disk_usage "$FILENAME") -gt $((1024*1024)) ]; then
unusable=true
fi
$QEMU_IMG create -f raw -o preallocation=full "$FILENAME" 5M > /dev/null
if [ $(disk_usage "$FILENAME") -lt $((4*1024*1024)) ]; then
unusable=true
fi
rm -f "$FILENAME"
if $unusable; then
_notrun "file system on $TEST_DIR does not handle sparse files nicely"
fi
}
# Check that a set of devices is available in the QEMU binary
#
_require_devices()
+6 -3
View File
@@ -40,6 +40,7 @@ cd ..
_supported_fmt qcow2 raw # Format of the source. dst is always raw file
_supported_proto file
_supported_os Linux
_require_disk_usage
echo
echo "=== Initial image setup ==="
@@ -96,13 +97,15 @@ _send_qemu_cmd $h1 '{"execute": "blockdev-del", "arguments":
{"node-name": "dst"}}' 'return' \
| _filter_block_job_offset | _filter_block_job_len
$QEMU_IMG compare -U -f $IMGFMT -F raw $TEST_IMG.base $TEST_IMG
# Some filesystems can fudge allocations for various reasons; rather
# than expecting precise 2M and 20M images, it is better to allow for slop.
result=$(disk_usage $TEST_IMG)
if test $result -lt $((3*1024*1024)); then
if test $result -lt $((4*1024*1024)); then
actual=sparse
elif test $result = $((20*1024*1024)); then
elif test $result -gt $((19*1024*1024)); then
actual=full
else
actual=unknown
actual="unexpected size ($result)"
fi
echo "Destination is $actual; expected $expected"
}
@@ -32,6 +32,7 @@ cd ..
_supported_fmt raw
_supported_proto file
_supported_os Linux
_require_disk_usage
create_test_image() {
_make_test_img -f $IMGFMT 1m