summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2020-09-24 16:26:50 +0200
committerWilly Tarreau <w@1wt.eu>2020-10-07 18:45:03 +0200
commit8faf1bc232ff17e8227f7dce70e67bace11fcde5 (patch)
treec4b299cd5deb1581dfc118069c43e72ddfa30aaa
parentc39840ced736fcfd0d46df665d3a5468c665e55f (diff)
downloadhaproxy-8faf1bc232ff17e8227f7dce70e67bace11fcde5.tar.gz
MINOR: protocol: introduce protocol_{pause,resume}_all()
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.
-rw-r--r--include/haproxy/protocol.h14
-rw-r--r--src/protocol.c44
2 files changed, 58 insertions, 0 deletions
diff --git a/include/haproxy/protocol.h b/include/haproxy/protocol.h
index ac331c78d..a752f98d9 100644
--- a/include/haproxy/protocol.h
+++ b/include/haproxy/protocol.h
@@ -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.
diff --git a/src/protocol.c b/src/protocol.c
index 48bce766b..54b708332 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -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.