OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: "Eva Kurchatova (Virtuozzo)" <eva.kurchatova@virtuozzo.com>
To: Konstantin Khorenko <khorenko@virtuozzo.com>,
	Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>,
	OpenVZ devel list <devel@openvz.org>
Subject: Re: [Devel] [PATCH vz10 v2] selftests/uevent: do not fail on a netlink receive buffer overrun
Date: Wed, 26 Aug 2026 22:32:52 +0300	[thread overview]
Message-ID: <6d350b33-2b0c-49b6-8c08-bdb24df770e6@virtuozzo.com> (raw)
In-Reply-To: <20260824130922.444331-1-khorenko@virtuozzo.com>


On 8/24/26 16:09, Konstantin Khorenko wrote:
> 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@virtuozzo.com>
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
> ---
> Changes in v2:
> - keep __UEVENT_BUFFER_SIZE at 4KB and give SO_RCVBUF its own
>    __UEVENT_RCVBUF_SIZE.  v1 raised the shared macro, which sized the
>    socket queue correctly but also turned the per message buffer into a
>    128KB zero initialized array on the stack, while the kernel caps a
>    single uevent at UEVENT_BUFFER_SIZE, 2048 bytes.
> - retry recvmsg() on ENOBUFS instead of failing.  v1 only made the
>    overrun less likely; the test still died on the first one, even
>    though do_test() triggers ten uevents precisely so that drops are
>    tolerated.
> - subject and commit message updated accordingly.
>
>   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 8062804ff759..735eb8138c44 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;

I was originally concerned about spinning on recvmsg(), but considering 
the socket is blocking, and recvmsg() should consume the error once, 
this should be fine.

Otherwise, this is a good improvement over the v1.


Acknowledged-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  parent reply	other threads:[~2026-08-26 19:34 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 15:03 [Devel] [PATCH vz10] selftests/uevent: give the netlink socket a usable receive buffer Eva Kurchatova
2026-08-24  8:34 ` Vasileios Almpanis
2026-08-24 13:09 ` [Devel] [PATCH vz10 v2] selftests/uevent: do not fail on a netlink receive buffer overrun Konstantin Khorenko
2026-08-26 16:49   ` Konstantin Khorenko
2026-08-26 19:32   ` Eva Kurchatova (Virtuozzo) [this message]
2026-08-27 12:28   ` [Devel] [PATCH RHEL10 COMMIT] " Konstantin Khorenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6d350b33-2b0c-49b6-8c08-bdb24df770e6@virtuozzo.com \
    --to=eva.kurchatova@virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=khorenko@virtuozzo.com \
    --cc=vasileios.almpanis@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox