MINOR: config: Add threads support for "process" option on "bind" lines
It is now possible on a "bind" line (or a "stats socket" line) to specify the
thread set allowed to process listener's connections. For instance:
# HTTPS connections will be processed by all threads but the first and HTTP
# connection will be processed on the first thread.
bind *:80 process 1/1
bind *:443 ssl crt mycert.pem process 1/2-
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 13c4f9e..e756d41 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10858,23 +10858,29 @@
the server's preference is enforced. This option is also available on
global statement "ssl-default-bind-options".
-process [ all | odd | even | <process_num>[-[<process_num>]] ]
- This restricts the list of processes on which this listener is allowed to
- run. It does not enforce any process but eliminates those which do not match.
- If the frontend uses a "bind-process" setting, the intersection between the
- two is applied. If in the end the listener is not allowed to run on any
- remaining process, a warning is emitted, and the listener will either run on
- the first process of the listener if a single process was specified, or on
- all of its processes if multiple processes were specified. For the unlikely
- case where several ranges are needed, this directive may be repeated. Ranges
- can be partially defined. The higher bound can be omitted. In such case, it
- is replaced by the corresponding maximum value. The main purpose of this
- directive is to be used with the stats sockets and have one different socket
- per process. The second purpose is to have multiple bind lines sharing the
- same IP:port but not the same process in a listener, so that the system can
- distribute the incoming connections into multiple queues and allow a smoother
- inter-process load balancing. Currently Linux 3.9 and above is known for
- supporting this. See also "bind-process" and "nbproc".
+process <process-set>[/<thread-set>]
+ This restricts the list of processes and/or threads on which this listener is
+ allowed to run. It does not enforce any process but eliminates those which do
+ not match. If the frontend uses a "bind-process" setting, the intersection
+ between the two is applied. If in the end the listener is not allowed to run
+ on any remaining process, a warning is emitted, and the listener will either
+ run on the first process of the listener if a single process was specified,
+ or on all of its processes if multiple processes were specified. If a thread
+ set is specified, it limits the threads allowed to process inoming
+ connections for this listener, for the corresponding process set. For the
+ unlikely case where several ranges are needed, this directive may be
+ repeated. <process-set> and <thread-set> must use the format
+
+ all | odd | even | number[-[number]]
+
+ Ranges can be partially defined. The higher bound can be omitted. In such
+ case, it is replaced by the corresponding maximum value. The main purpose of
+ this directive is to be used with the stats sockets and have one different
+ socket per process. The second purpose is to have multiple bind lines sharing
+ the same IP:port but not the same process in a listener, so that the system
+ can distribute the incoming connections into multiple queues and allow a
+ smoother inter-process load balancing. Currently Linux 3.9 and above is known
+ for supporting this. See also "bind-process" and "nbproc".
ssl
This setting is only available when support for OpenSSL was built in. It
diff --git a/include/types/listener.h b/include/types/listener.h
index b92c35e..c55569c 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -33,6 +33,7 @@
#include <common/config.h>
#include <common/mini-clist.h>
#include <common/hathreads.h>
+#include <common/standard.h>
#include <types/obj_type.h>
#include <eb32tree.h>
@@ -159,6 +160,7 @@
int is_ssl; /* SSL is required for these listeners */
int generate_certs; /* 1 if generate-certificates option is set, else 0 */
unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
+ unsigned long bind_thread[LONGBITS]; /* bitmask of threads (per processes) allowed to use these listeners */
struct { /* UNIX socket permissions */
uid_t uid; /* -1 to leave unchanged */
gid_t gid; /* -1 to leave unchanged */
diff --git a/src/listener.c b/src/listener.c
index c82ba36..09d38ac 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -941,14 +941,32 @@
/* parse the "process" bind keyword */
static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
- unsigned long set = 0;
+ char *slash;
+ unsigned long proc = 0, thread = 0;
+ int i;
- if (parse_process_number(args[cur_arg + 1], &set, NULL, err)) {
+ if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
+ *slash = 0;
+
+ if (parse_process_number(args[cur_arg + 1], &proc, NULL, err)) {
memprintf(err, "'%s' : %s", args[cur_arg], *err);
return ERR_ALERT | ERR_FATAL;
}
+ if (slash) {
+ if (parse_process_number(slash+1, &thread, NULL, err)) {
+ memprintf(err, "'%s' : %s", args[cur_arg], *err);
+ return ERR_ALERT | ERR_FATAL;
+ }
+ *slash = '/';
+ }
+
- conf->bind_proc |= set;
+ conf->bind_proc |= proc;
+ if (thread) {
+ for (i = 0; i < LONGBITS; i++)
+ if (!proc || (proc & (1UL << i)))
+ conf->bind_thread[i] |= thread;
+ }
return 0;
}