From c644fa9bf5f9b94e4bcd1e806222b96f63f8d175 Mon Sep 17 00:00:00 2001 From: Christopher Faulet <cfaulet@haproxy.com> Date: Thu, 23 Nov 2017 22:44:11 +0100 Subject: [PATCH] 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- --- doc/configuration.txt | 40 +++++++++++++++++++++++----------------- include/types/listener.h | 2 ++ src/listener.c | 24 +++++++++++++++++++++--- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 13c4f9edf..e756d41e3 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -10858,23 +10858,29 @@ prefer-client-ciphers 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 b92c35e2d..c55569cd3 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 @@ struct bind_conf { 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 c82ba36e0..09d38acef 100644 --- a/src/listener.c +++ b/src/listener.c @@ -941,14 +941,32 @@ static int bind_parse_nice(char **args, int cur_arg, struct proxy *px, struct bi /* 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; } - conf->bind_proc |= set; + 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 |= proc; + if (thread) { + for (i = 0; i < LONGBITS; i++) + if (!proc || (proc & (1UL << i))) + conf->bind_thread[i] |= thread; + } return 0; }