]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: introduce protocol_{pause,resume}_all()
authorWilly Tarreau <w@1wt.eu>
Thu, 24 Sep 2020 14:26:50 +0000 (16:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 Oct 2020 09:27:30 +0000 (11:27 +0200)
These two functions are used to pause and resume all listeners of
all protocols. They use the standard listener functions for this
so they're supposed to handle the situation gracefully regardless
of the upper proxies' states, and they will report completion on
proxies once the switch is performed.

It might be nice to define a particular "failed" state for listeners
that cannot resume and to count them on proxies in order to mention
that they're definitely stuck. On the other hand, the current
situation is retryable which is quite appreciable as well.

include/haproxy/protocol.h
src/protocol.c

index ac331c78d6ecc8234c895511a13f1ee192e7a6c1..a752f98d96f8ebb98eb0f7b236744b41bb25d531 100644 (file)
@@ -50,6 +50,20 @@ int protocol_bind_all(int verbose);
  */
 int protocol_unbind_all(void);
 
+/* pauses all listeners of all registered protocols. This is typically
+ * used on SIG_TTOU to release all listening sockets for the time needed to
+ * try to bind a new process. The listeners enter LI_PAUSED. It returns
+ * ERR_NONE, with ERR_FATAL on failure.
+ */
+int protocol_pause_all(void);
+
+/* resumes all listeners of all registered protocols. This is typically used on
+ * SIG_TTIN to re-enable listening sockets after a new process failed to bind.
+ * The listeners switch to LI_READY/LI_FULL. It returns ERR_NONE, with ERR_FATAL
+ * on failure.
+ */
+int protocol_resume_all(void);
+
 /* enables all listeners of all registered protocols. This is intended to be
  * used after a fork() to enable reading on all file descriptors. Returns a
  * composition of ERR_NONE, ERR_RETRYABLE, ERR_FATAL.
index 48bce766b6dab11394ed7c9aa0f2b1a2537c8b89..54b708332729fe38b143ebc7ba72d57cf66caeee 100644 (file)
@@ -151,6 +151,50 @@ int protocol_unbind_all(void)
        return err;
 }
 
+/* pauses all listeners of all registered protocols. This is typically
+ * used on SIG_TTOU to release all listening sockets for the time needed to
+ * try to bind a new process. The listeners enter LI_PAUSED. It returns
+ * ERR_NONE, with ERR_FATAL on failure.
+ */
+int protocol_pause_all(void)
+{
+       struct protocol *proto;
+       struct listener *listener;
+       int err;
+
+       err = 0;
+       HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
+       list_for_each_entry(proto, &protocols, list) {
+               list_for_each_entry(listener, &proto->listeners, rx.proto_list)
+                       if (!pause_listener(listener))
+                               err |= ERR_FATAL;
+       }
+       HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
+       return err;
+}
+
+/* resumes all listeners of all registered protocols. This is typically used on
+ * SIG_TTIN to re-enable listening sockets after a new process failed to bind.
+ * The listeners switch to LI_READY/LI_FULL. It returns ERR_NONE, with ERR_FATAL
+ * on failure.
+ */
+int protocol_resume_all(void)
+{
+       struct protocol *proto;
+       struct listener *listener;
+       int err;
+
+       err = 0;
+       HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
+       list_for_each_entry(proto, &protocols, list) {
+               list_for_each_entry(listener, &proto->listeners, rx.proto_list)
+                       if (!resume_listener(listener))
+                               err |= ERR_FATAL;
+       }
+       HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
+       return err;
+}
+
 /* enables all listeners of all registered protocols. This is intended to be
  * used after a fork() to enable reading on all file descriptors. Returns a
  * composition of ERR_NONE, ERR_RETRYABLE, ERR_FATAL.