From 102df613a9e29eca811f3254b4aa9dbbbd17f63f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 7 May 2014 23:56:38 +0200 Subject: [PATCH] MEDIUM: config: check the bind-process settings according to nbproc When a bind-process setting is present in a frontend or backend, we now verify that the specified process range at least shares one common process with those defined globally by nbproc. Then if the value is set, it is reduced to the one enforced by nbproc. A warning is emitted if process count does not match, and the fix is done the following way : - if a single process was specified in the range, it's remapped to process #1 - if more than one process was specified, the binding is removed and all processes are usable. Note that since backends may inherit their settings from frontends, depending on the declaration order, they may or may not be reported as warnings. --- doc/configuration.txt | 7 ++-- src/cfgparse.c | 79 ++++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 3ec161e3f..e178678c1 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1849,9 +1849,10 @@ bind-process [ all | odd | even | [-] ] ... number The instance will be enabled on this process number or range, whose values must all be between 1 and 32 or 64 depending on - the machine's word size. You must be careful not to reference - a process number greater than the configured global.nbproc, - otherwise some instances might be missing from all processes. + the machine's word size. If a proxy is bound to process + numbers greater than the configured global.nbproc, it will + either be forced to process #1 if a single process was + specified, or to all processes otherwise. This keyword limits binding of certain instances to certain processes. This is useful in order not to have too many processes listening to the same diff --git a/src/cfgparse.c b/src/cfgparse.c index 703239739..0920eac5f 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -5851,8 +5851,38 @@ int check_config_validity() continue; } - /* number of processes this proxy is bound to */ - nbproc = curproxy->bind_proc ? popcount(curproxy->bind_proc) : global.nbproc; + /* Check multi-process mode compatibility for the current proxy */ + + if (curproxy->bind_proc) { + /* an explicit bind-process was specified, let's check how many + * processes remain. + */ + nbproc = popcount(curproxy->bind_proc); + + curproxy->bind_proc &= nbits(global.nbproc); + if (!curproxy->bind_proc && nbproc == 1) { + Warning("Proxy '%s': the process specified on the 'bind-process' directive refers to a process number that is higher than global.nbproc. The proxy has been forced to run on process 1 only.\n", curproxy->id); + curproxy->bind_proc = 1; + } + else if (!curproxy->bind_proc && nbproc > 1) { + Warning("Proxy '%s': all processes specified on the 'bind-process' directive refer to numbers that are all higher than global.nbproc. The directive was ignored and the proxy will run on all processes.\n", curproxy->id); + curproxy->bind_proc = 0; + } + } + + /* here, if bind_proc is null, it means no limit, otherwise it's explicit. + * We now check how many processes the proxy will effectively run on. + */ + + nbproc = global.nbproc; + if (curproxy->bind_proc) + nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc)); + + if (global.nbproc > 1 && curproxy->table.peers.name) { + Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n", + curproxy->id); + cfgerr++; + } switch (curproxy->mode) { case PR_MODE_HEALTH: @@ -6854,41 +6884,22 @@ out_uri_auth_compat: #endif /* USE_OPENSSL */ } - /* Check multi-process mode compatibility for the current proxy */ - if (global.nbproc > 1) { - int nbproc = 0; - if (curproxy->bind_proc) { - int proc; - for (proc = 0; proc < global.nbproc; proc++) { - if (curproxy->bind_proc & (1UL << proc)) { - nbproc++; - } + if (nbproc > 1) { + if (curproxy->uri_auth) { + Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n", + curproxy->id); + if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) { + Warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n", + curproxy->id); } - } else { - nbproc = global.nbproc; } - if (curproxy->table.peers.name) { - Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n", - curproxy->id); - cfgerr++; + if (curproxy->appsession_name) { + Warning("Proxy '%s': appsession will not work correctly in multi-process mode.\n", + curproxy->id); } - if (nbproc > 1) { - if (curproxy->uri_auth) { - Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n", - curproxy->id); - if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) { - Warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n", - curproxy->id); - } - } - if (curproxy->appsession_name) { - Warning("Proxy '%s': appsession will not work correctly in multi-process mode.\n", - curproxy->id); - } - if (!LIST_ISEMPTY(&curproxy->sticking_rules)) { - Warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n", - curproxy->id); - } + if (!LIST_ISEMPTY(&curproxy->sticking_rules)) { + Warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n", + curproxy->id); } }