From: Willy Tarreau Date: Wed, 26 Aug 2020 09:44:17 +0000 (+0200) Subject: MEDIUM: fd: replace usages of fd_remove() with fd_stop_both() X-Git-Tag: v2.3-dev4~72 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=67672459c72328047c5b24c8a721789fef8b13d9;p=thirdparty%2Fhaproxy.git MEDIUM: fd: replace usages of fd_remove() with fd_stop_both() We used to require fd_remove() to remove an FD from a poller when we still had the FD cache and it was not possible to directly act on the pollers. Nowadays we don't need this anymore as the pollers will automatically unregister disabled FDs. The fd_remove() hack is particularly problematic because it additionally hides the FD from the known FD list and could make one think it's closed. It's used at two places: - with the async SSL engine - with the listeners (when unbinding from an fd for another process) Let's just use fd_stop_both() instead, which will propagate down the stack to do the right thing, without removing the FD from the array of known ones. Now when dumping FDs using "show fd" on a process which still knows some of the other workers' FDs, the FD will properly be listed with a listener state equal to "ZOM" for "zombie". This guarantees that the FD is still known and will properly be passed using _getsocks(). --- diff --git a/src/listener.c b/src/listener.c index cad0e0cc84..6e635e367a 100644 --- a/src/listener.c +++ b/src/listener.c @@ -503,13 +503,12 @@ void do_unbind_listener(struct listener *listener, int do_close) MT_LIST_DEL(&listener->wait_queue); if (listener->state >= LI_PAUSED) { + listener->state = LI_ASSIGNED; + fd_stop_both(listener->fd); if (do_close) { fd_delete(listener->fd); listener->fd = -1; } - else - fd_remove(listener->fd); - listener->state = LI_ASSIGNED; } } diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 64208daef5..64c86b1168 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -700,7 +700,7 @@ void ssl_async_fd_free(int fd) SSL_get_all_async_fds(ssl, all_fd, &num_all_fds); for (i=0 ; i < num_all_fds ; i++) - fd_remove(all_fd[i]); + fd_stop_both(all_fd[i]); /* Now we can safely call SSL_free, no more pending job in engines */ SSL_free(ssl); @@ -731,7 +731,7 @@ static inline void ssl_async_process_fds(struct ssl_sock_ctx *ctx) /* We remove unused fds from the fdtab */ for (i=0 ; i < num_del_fds ; i++) - fd_remove(del_fd[i]); + fd_stop_both(del_fd[i]); /* We add new fds to the fdtab */ for (i=0 ; i < num_add_fds ; i++) { @@ -6137,12 +6137,12 @@ static void ssl_sock_close(struct connection *conn, void *xprt_ctx) { } /* Else we can remove the fds from the fdtab * and call SSL_free. - * note: we do a fd_remove and not a delete + * note: we do a fd_stop_both and not a delete * because the fd is owned by the engine. * the engine is responsible to close */ for (i=0 ; i < num_all_fds ; i++) - fd_remove(all_fd[i]); + fd_stop_both(all_fd[i]); } #endif SSL_free(ctx->ssl);