From 374e9af35840c0d6294036e0b6c82c3229dc255a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 9 Oct 2020 15:47:17 +0200 Subject: [PATCH] MEDIUM: listener: let do_unbind_listener() decide whether to close or not The listener contains all the information needed to decide to close on unbind or not. The rule is the following (when we're not stopping): - worker process unbinding from a worker's FD with socket transfer enabled => keep - master process unbinding from a master's inherited FD => keep - master process unbinding from a master's FD => close - master process unbinding from a worker's FD => close - worker process unbinding from a master's FD => close - worker process unbinding from a worker's FD => close Let's translate that into the function and stop using the do_close argument that is a bit obscure for callers. It was not yet removed to ease code testing. --- src/listener.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/listener.c b/src/listener.c index 92463534b..5002879dc 100644 --- a/src/listener.c +++ b/src/listener.c @@ -581,14 +581,32 @@ void do_unbind_listener(struct listener *listener, int do_close) } out_close: - if (do_close) { - listener->rx.flags &= ~RX_F_BOUND; - if (listener->rx.fd != -1) - fd_delete(listener->rx.fd); - listener->rx.fd = -1; - if (listener->state > LI_ASSIGNED) - listener_set_state(listener, LI_ASSIGNED); - } + /* There are a number of situations where we prefer to keep the FD and + * not to close it (unless we're stopping, of course): + * - worker process unbinding from a worker's FD with socket transfer enabled => keep + * - master process unbinding from a master's inherited FD => keep + * - master process unbinding from a master's FD => close + * - master process unbinding from a worker's FD => close + * - worker process unbinding from a master's FD => close + * - worker process unbinding from a worker's FD => close + */ + + if (!stopping && !master && + !(listener->options & LI_O_MWORKER) && + (global.tune.options & GTUNE_SOCKET_TRANSFER)) + return; + + if (!stopping && master && + listener->options & LI_O_MWORKER && + listener->rx.flags & RX_F_INHERITED) + return; + + listener->rx.flags &= ~RX_F_BOUND; + if (listener->rx.fd != -1) + fd_delete(listener->rx.fd); + listener->rx.fd = -1; + if (listener->state > LI_ASSIGNED) + listener_set_state(listener, LI_ASSIGNED); } /* This function closes the listening socket for the specified listener,