From 715fb4effaa7f35e642056d2a10d5b8c393bfac0 Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 21 Apr 2023 18:38:53 +0200 Subject: [PATCH] terminal: make a terminal FDs non-blocking Let's prevent freezes on read(2) by making a terminal FDs non-blocking. It was discovered that there is an issue with io_uring mainloop when multishot poll (IORING_POLL_ADD_MULTI) mode is enabled. Sometimes false-positive poll events are put into a CQ. It makes further read(2) stuck forever and blocks all mainloop processing for an infinite time. Signed-off-by: Alexander Mikhalitsyn --- src/lxc/terminal.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index a1dcc2dc7..de4328fb7 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -334,9 +334,12 @@ static int lxc_terminal_ptx_io(struct lxc_terminal *terminal) int r, w, w_log, w_rbuf; w = r = lxc_read_nointr(terminal->ptx, buf, sizeof(buf)); - if (r <= 0) - return -1; + if (r <= 0) { + if (errno == EWOULDBLOCK) + return 0; + return -1; + } w_rbuf = w_log = 0; /* write to peer first */ if (terminal->peer >= 0) @@ -370,8 +373,12 @@ static int lxc_terminal_peer_io(struct lxc_terminal *terminal) int r, w; w = r = lxc_read_nointr(terminal->peer, buf, sizeof(buf)); - if (r <= 0) + if (r <= 0) { + if (errno == EWOULDBLOCK) + return 0; + return -1; + } w = lxc_write_nointr(terminal->ptx, buf, r); if (w != r) @@ -415,6 +422,9 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) int ret; if (terminal->peer >= 0) { + if (fd_make_nonblocking(terminal->peer)) + return log_error_errno(-1, errno, "Failed to make terminal peer fd non-blocking"); + ret = lxc_mainloop_add_handler(terminal->descr, terminal->peer, lxc_terminal_peer_io_handler, default_cleanup_handler, @@ -452,6 +462,9 @@ int lxc_terminal_mainloop_add(struct lxc_async_descr *descr, return 0; } + if (fd_make_nonblocking(terminal->ptx)) + return log_error_errno(-1, errno, "Failed to make terminal ptx fd non-blocking"); + ret = lxc_mainloop_add_handler(descr, terminal->ptx, lxc_terminal_ptx_io_handler, default_cleanup_handler, -- 2.39.5