From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>, passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 2/3] conf, tap, repair: Uniformly use non-blocking accept() on Unix sockets
Date: Wed, 13 May 2026 14:14:22 +1000 [thread overview]
Message-ID: <20260513041423.2446716-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260513041423.2446716-1-david@gibson.dropbear.id.au>
sock_unix(), which creates a listening Unix socket, doesn't set the
SOCK_NONBLOCK flag, meaning that accept() will block if called with no
pending connections. Generally, this doesn't matter because we only
accept() once we've received an epoll event indicating there's a pending
connection request.
Control connections (pesto) are an exception, because the way we queue
connections requires that we call accept() when we close one connection to
see if there's another one waiting. We rely on an EAGAIN here to know that
there's nothing waiting. To handle these we have an explicit fcntl() to
enable NONBLOCK on the control listening socket.
However, always using non-blocking accept() for Unix sockets would make
things a bit more uniform, and should be a bit less fragile in the case
that we ever somehow got a spurious connection event. So, alter
sock_unix() to always use the SOCK_NONBLOCK flag. Remove the control
socket's special case fcntl(), and adjust the error handling on each
Unix socket accept() for the new behaviour. As a bonus the last adds
reporting for accept() errors on tap socket connections.
we will need non-blocking accept() for the upcoming control/configuration
socket. Always add SOCK_NONBLOCK, which is more robust and in keeping with
the normal non-blocking style of passt.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
conf.c | 4 +---
repair.c | 4 ++--
tap.c | 5 +++++
util.c | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/conf.c b/conf.c
index 029b9c7c..dec43fca 100644
--- a/conf.c
+++ b/conf.c
@@ -1091,8 +1091,6 @@ static void conf_open_files(struct ctx *c)
die_perror("Couldn't open control socket %s",
c->control_path);
}
- if (fcntl(c->fd_control_listen, F_SETFL, O_NONBLOCK))
- die_perror("Couldn't set O_NONBLOCK on control socket");
} else {
c->fd_control_listen = -1;
}
@@ -2087,7 +2085,7 @@ retry:
fd = accept4(c->fd_control_listen, NULL, NULL, SOCK_CLOEXEC);
if (fd < 0) {
if (errno != EAGAIN)
- warn_perror("accept4() on configuration listening socket");
+ warn_perror("Error accept()ing configuration socket");
return;
}
diff --git a/repair.c b/repair.c
index 3e0e3e0a..42c4ae97 100644
--- a/repair.c
+++ b/repair.c
@@ -101,8 +101,8 @@ int repair_listen_handler(struct ctx *c, uint32_t events)
if ((c->fd_repair = accept4(c->fd_repair_listen, NULL, NULL,
SOCK_CLOEXEC)) < 0) {
- rc = errno;
- debug_perror("accept4() on TCP_REPAIR helper listening socket");
+ if ((rc = errno) != EAGAIN)
+ warn_perror("Error accept()ing repair helper");
return rc;
}
diff --git a/tap.c b/tap.c
index e7cac9df..fda2da9b 100644
--- a/tap.c
+++ b/tap.c
@@ -1491,6 +1491,11 @@ void tap_listen_handler(struct ctx *c, uint32_t events)
}
c->fd_tap = accept4(c->fd_tap_listen, NULL, NULL, SOCK_CLOEXEC);
+ if (c->fd_tap < 0) {
+ if (errno != EAGAIN)
+ warn_perror("Error accepting tap client");
+ return;
+ }
if (!getsockopt(c->fd_tap, SOL_SOCKET, SO_PEERCRED, &ucred, &len))
info("accepted connection from PID %i", ucred.pid);
diff --git a/util.c b/util.c
index 73c9d51d..204391c7 100644
--- a/util.c
+++ b/util.c
@@ -238,7 +238,7 @@ int sock_l4_dualstack_any(const struct ctx *c, enum epoll_type type,
*/
int sock_unix(char *sock_path)
{
- int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
};
--
2.54.0
next prev parent reply other threads:[~2026-05-13 4:14 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-13 4:14 [PATCH 0/3] More caution with NONBLOCK flag " David Gibson
2026-05-13 4:14 ` [PATCH 1/3] treewide: Add SOCK_CLOEXEC to accept() calls that are missing it David Gibson
2026-05-13 4:14 ` David Gibson [this message]
2026-05-13 5:51 ` [PATCH 2/3] conf, tap, repair: Uniformly use non-blocking accept() on Unix sockets David Gibson
2026-05-13 4:14 ` [PATCH 3/3] conf, repair, tap: More caution about blocking flag " David Gibson
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=20260513041423.2446716-3-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.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.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).