]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: listener: let do_unbind_listener() decide whether to close or not
authorWilly Tarreau <w@1wt.eu>
Fri, 9 Oct 2020 13:47:17 +0000 (15:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 Oct 2020 16:41:48 +0000 (18:41 +0200)
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

index 92463534b9c48c3b09ded9833f68e142b55e69c9..5002879dceb198ee67c0b082c130771e143b7c24 100644 (file)
@@ -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,