]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: listener: keep a single thread-mask and warn on "process" misuse
authorWilly Tarreau <w@1wt.eu>
Sat, 2 Feb 2019 12:14:34 +0000 (13:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 27 Feb 2019 13:27:07 +0000 (14:27 +0100)
Now that nbproc and nbthread are exclusive, we can still provide more
detailed explanations about what we've found in the config when a bind
line appears on multiple threads and processes at the same time, then
ignore the setting.

This patch reduces the listener's thread mask to a single mask instead
of an array of masks per process. Now we have only one thread mask and
one process mask per bind-conf. This removes ~504 bytes of RAM per
bind-conf and will simplify handling of thread masks.

If a "bind" line only refers to process numbers not found by its parent
frontend or not covered by the global nbproc directive, or to a thread
not covered by the global nbthread directive, a warning is emitted saying
what will be used instead.

doc/configuration.txt
include/types/listener.h
src/cfgparse.c
src/listener.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_uxst.c

index 1c42d065d9f8aeda947f957528b8e4e8a52cdcb9..aedced58d5605968203e7c3e118efeb765e0bffb 100644 (file)
@@ -11323,7 +11323,7 @@ prefer-client-ciphers
   the client cipher list.
 
 process <process-set>[/<thread-set>]
-  This restricts the list of processes and/or threads on which this listener is
+  This restricts the list of processes 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
@@ -11331,9 +11331,11 @@ process <process-set>[/<thread-set>]
   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 incoming
-  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
+  connections for this listener, for the the process set. If multiple processes
+  and threads are configured, a warning is emitted, as it either results from a
+  configuration error or a misunderstanding of these models. 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]]
 
index 9c0ebde0693a7cc44a0b04c5496dd4dc750d384b..1203d17016c7c7c04549d62ffd3cc48a200d2bef 100644 (file)
@@ -166,7 +166,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[MAX_PROCS]; /* bitmask of threads (per processes) allowed to use these listeners */
+       unsigned long bind_thread; /* bitmask of threads allowed to use these listeners */
        struct {                   /* UNIX socket permissions */
                uid_t uid;         /* -1 to leave unchanged */
                gid_t gid;         /* -1 to leave unchanged */
index 85d8dd53aa01587872d92c4ecc89cb8af4bc9c5e..16d92512cd7b62ccc59f91178876ca9cfea42bc8 100644 (file)
@@ -2304,8 +2304,7 @@ int check_config_validity()
 #endif
 
                        /* detect and address thread affinity inconsistencies */
-                       nbproc = my_ffsl(proc_mask(bind_conf->bind_proc)) - 1;
-                       mask = thread_mask(bind_conf->bind_thread[nbproc]);
+                       mask = thread_mask(bind_conf->bind_thread);
                        if (!(mask & all_threads_mask)) {
                                unsigned long new_mask = 0;
 
@@ -2314,33 +2313,28 @@ int check_config_validity()
                                        mask >>= global.nbthread;
                                }
 
-                               for (nbproc = 0; nbproc < MAX_PROCS; nbproc++) {
-                                       if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
-                                               bind_conf->bind_thread[nbproc] = new_mask;
-                               }
+                               bind_conf->bind_thread = new_mask;
                                ha_warning("Proxy '%s': the thread range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to thread numbers out of the range defined by the global 'nbthread' directive. The thread numbers were remapped to existing threads instead (mask 0x%lx).\n",
                                           curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
                        }
 
                        /* detect process and nbproc affinity inconsistencies */
-                       if (!bind_conf->bind_proc)
-                               continue;
-
-                       mask = proc_mask(curproxy->bind_proc) & all_proc_mask;
-                       /* mask cannot be null here thanks to the previous checks */
-
-                       nbproc = my_popcountl(bind_conf->bind_proc);
-                       bind_conf->bind_proc &= mask;
-
-                       if (!bind_conf->bind_proc && nbproc == 1) {
-                               ha_warning("Proxy '%s': the process number specified on the 'process' directive of 'bind %s' at [%s:%d] refers to a process not covered by the proxy. This has been fixed by forcing it to run on the proxy's first process only.\n",
-                                          curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
-                               bind_conf->bind_proc = mask & ~(mask - 1);
-                       }
-                       else if (!bind_conf->bind_proc && nbproc > 1) {
-                               ha_warning("Proxy '%s': the process range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to processes not covered by the proxy. The directive was ignored so that all of the proxy's processes are used.\n",
-                                          curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
-                               bind_conf->bind_proc = 0;
+                       mask = proc_mask(bind_conf->bind_proc) & proc_mask(curproxy->bind_proc);
+                       if (!(mask & all_proc_mask)) {
+                               mask = proc_mask(curproxy->bind_proc) & all_proc_mask;
+                               nbproc = my_popcountl(bind_conf->bind_proc);
+                               bind_conf->bind_proc = proc_mask(bind_conf->bind_proc) & mask;
+
+                               if (!bind_conf->bind_proc && nbproc == 1) {
+                                       ha_warning("Proxy '%s': the process number specified on the 'process' directive of 'bind %s' at [%s:%d] refers to a process not covered by the proxy. This has been fixed by forcing it to run on the proxy's first process only.\n",
+                                                  curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
+                                       bind_conf->bind_proc = mask & ~(mask - 1);
+                               }
+                               else if (!bind_conf->bind_proc && nbproc > 1) {
+                                       ha_warning("Proxy '%s': the process range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to processes not covered by the proxy. The directive was ignored so that all of the proxy's processes are used.\n",
+                                                  curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
+                                       bind_conf->bind_proc = 0;
+                               }
                        }
                }
 
index f8745e33607fd8c78f9652305848eaef8dd40612..117b9c43f26ef60a544b1d5baaa868c6d5cd3e4b 100644 (file)
@@ -954,7 +954,6 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct
 {
        char *slash;
        unsigned long proc = 0, thread = 0;
-       int i;
 
        if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
                *slash = 0;
@@ -973,11 +972,7 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct
        }
 
        conf->bind_proc |= proc;
-       if (thread) {
-               for (i = 0; i < MAX_PROCS; i++)
-                       if (!proc || (proc & (1UL << i)))
-                               conf->bind_thread[i] |= thread;
-       }
+       conf->bind_thread |= thread;
        return 0;
 }
 
index 9105dd2f9e0234c9ad302d6466eb069ae8f366f6..713da370ab8c76b43989d138d5593e9491c19a0e 100644 (file)
@@ -153,7 +153,7 @@ static int sockpair_bind_listener(struct listener *listener, char *errmsg, int e
        listener->state = LI_LISTEN;
 
        fd_insert(fd, listener, listener->proto->accept,
-                 thread_mask(listener->bind_conf->bind_thread[relative_pid-1]));
+                 thread_mask(listener->bind_conf->bind_thread));
 
        return err;
 
index e4b8f63d75e8271852f15508feaf8f31816d22da..28b77503e52f79acc3b4bef3d021f312c814794a 100644 (file)
@@ -1076,7 +1076,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
        listener->state = LI_LISTEN;
 
        fd_insert(fd, listener, listener->proto->accept,
-                 thread_mask(listener->bind_conf->bind_thread[relative_pid-1]));
+                 thread_mask(listener->bind_conf->bind_thread));
 
  tcp_return:
        if (msg && errlen) {
index 7fc145b8cf5d74d744d6accad3e68f87336d471e..d454d4ca132074b9be51ec798b23a10a5518ee2a 100644 (file)
@@ -340,7 +340,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
        listener->state = LI_LISTEN;
 
        fd_insert(fd, listener, listener->proto->accept,
-                 thread_mask(listener->bind_conf->bind_thread[relative_pid-1]));
+                 thread_mask(listener->bind_conf->bind_thread));
 
        return err;