File util-linux-agetty-netlink-fix4.patch of Package util-linux

From fa9b5740f67bc64d7b58f9b2fcc4f2883d7dcc91 Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <sbrabec@suse.cz>
Date: Fri, 10 Oct 2025 13:17:26 +0200
Subject: [PATCH 6/6] agetty: Process all data from ul_nl_process()

However select() normally triggers immediately after a partial read, it does not
happen for netlink socket. It keeps unprocessed data until the next netlink
message appears. It causes raising processing delays.

Always read all data. It also potentially decreases number of issue redraws.

Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
---
 include/netlink.h   |  6 +++++-
 term-utils/agetty.c | 14 +++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/netlink.h b/include/netlink.h
index 3d7c3da04..ee4917b39 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -40,7 +40,9 @@
 			     * reach unprocessed NLMSG_DONE */
 #define	UL_NL_SOFT_ERROR 4  /* soft error, indicating a race condition or
 			     * message relating to events before program
-			     * start); could be optionally ignored */
+			     * start); could be optionally ignored and it
+			     * should not considered as a reason to leave the
+			     * processing */
 
 struct ul_nl_data;
 
@@ -139,6 +141,8 @@ int ul_nl_request_dump(struct ul_nl_data *nl, uint16_t nlmsg_type);
 /* Process netlink messages.
  * async: If true, return UL_NL_WOULDBLOCK immediately if there is no data
  *   ready. If false, wait for a message.
+ *   NOTE: You should read all data until you get UL_NL_WOULDBLOCK, otherwise
+ *         select() will not trigger even if there is a netlink message.
  * loop: If true, run in a loop until NLMSG_DONE is received. Returns after
  *   finishing a reply from ul_nl_request_dump(), otherwise it acts as an
  *   infinite loop. If false, it returns after processing one message.
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index ec922bd11..08d009261 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -1654,9 +1654,17 @@ static int wait_for_term_input(struct issue *ie, int fd)
 		}
 
 		if (ie->nl.fd >= 0 && FD_ISSET(ie->nl.fd, &rfds)) {
-			/* We are ignoring errors here to prevent unability of
-			 * further processing. */
-			ul_nl_process(&(ie->nl), UL_NL_ASYNC, UL_NL_ONESHOT);
+			int rc;
+
+			/* We are looping until it returns UL_NL_WOULDBLOCK.
+			 * To prevent infinite loop, we are leaving on any other
+			 * error except UL_NL_SOFT_ERROR. To prevent unability
+			 * of further processing, we never exit. */
+			do {
+				rc = ul_nl_process(&(ie->nl), UL_NL_ASYNC,
+						   UL_NL_ONESHOT);
+			}
+			while (!rc || rc == UL_NL_SOFT_ERROR);
 
 		/* Just drain the inotify buffer */
 		} else if (inotify_fd >= 0 && FD_ISSET(inotify_fd, &rfds)) {
-- 
2.48.1

openSUSE Build Service is sponsored by