[Devel] [PATCH RHEL10 COMMIT] selftests/uevent: do not fail on a netlink receive buffer overrun
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Aug 27 15:28:52 MSK 2026
The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-211.39.1.16.11.vz10
------>
commit dd27dfa9341d66afa10abd7e082b2c32dfd160d0
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date: Mon Aug 24 15:09:22 2026 +0200
selftests/uevent: do not fail on a netlink receive buffer overrun
SO_RCVBUF is set to __UEVENT_BUFFER_SIZE, 4KB, which a busy machine
overruns while the test is listening:
No buffer space available - Failed to receive uevent
Two things are wrong here.
The socket queue is sized after a single message, while do_test()
deliberately triggers ten uevents "to account for the case where the
kernel might drop some", so the queue has to hold more than one.
Give it its own size and leave the message buffer alone: the kernel caps
a single uevent at UEVENT_BUFFER_SIZE, 2048 bytes, so 4KB per message is
already generous.
The receive loop then treats every error as fatal, ENOBUFS included,
which defeats those ten uevents. Netlink clears the error after
reporting it once, so the copies still queued, or still on their way,
are perfectly receivable. Retry instead.
do_test() bounds the listener with a two second sigtimedwait(), so a
retry cannot hang the test.
https://virtuozzo.atlassian.net/browse/VSTOR-139674
Feature: fix selftests
Reported-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Reviewed-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
---
tools/testing/selftests/uevent/uevent_filtering.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/uevent/uevent_filtering.c b/tools/testing/selftests/uevent/uevent_filtering.c
index 8062804ff759a..735eb8138c448 100644
--- a/tools/testing/selftests/uevent/uevent_filtering.c
+++ b/tools/testing/selftests/uevent/uevent_filtering.c
@@ -23,6 +23,11 @@
#define __DEV_FULL "/sys/devices/virtual/mem/full/uevent"
#define __UEVENT_BUFFER_SIZE (2048 * 2)
+/*
+ * The socket queue has to hold more than a single message: the test
+ * triggers ten uevents and a busy machine overruns a small buffer.
+ */
+#define __UEVENT_RCVBUF_SIZE (2048 * 64)
#define __UEVENT_HEADER "add@/devices/virtual/mem/full"
#define __UEVENT_HEADER_LEN sizeof("add@/devices/virtual/mem/full")
#define __UEVENT_LISTEN_ALL -1
@@ -78,7 +83,7 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
{
int sk_fd, ret;
socklen_t sk_addr_len;
- int rcv_buf_sz = __UEVENT_BUFFER_SIZE;
+ int rcv_buf_sz = __UEVENT_RCVBUF_SIZE;
uint64_t sync_add = 1;
struct sockaddr_nl sk_addr = { 0 }, rcv_addr = { 0 };
char buf[__UEVENT_BUFFER_SIZE] = { 0 };
@@ -158,6 +163,12 @@ static int uevent_listener(unsigned long post_flags, bool expect_uevent,
ssize_t r;
r = recvmsg(sk_fd, &hdr, 0);
+ /*
+ * The queue overran. The kernel clears the error after
+ * reporting it once and more uevents are on their way.
+ */
+ if (r < 0 && errno == ENOBUFS)
+ continue;
if (r <= 0) {
fprintf(stderr, "%s - Failed to receive uevent\n", strerror(errno));
ret = -1;
More information about the Devel
mailing list