From 91b00c2194b728ccd61133cca83f03de3650b674 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 16 Sep 2014 13:41:21 +0200 Subject: [PATCH 10/13] MEDIUM: config: compute the exact bind-process before listener's maxaccept This is a continuation of previous patch, the listener's maxaccept is divided by the number of processes, so it's best if we can swap the two blocks so that the number of processes is already known when computing the maxaccept value. (cherry picked from commit 419ead8eca9237f9cc2ec32630d96fde333282ee) --- src/cfgparse.c | 156 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 81 insertions(+), 75 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index d53f69e..f3907bf 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6042,12 +6042,11 @@ int check_config_validity() proxy = next; } - while (curproxy != NULL) { + for (curproxy = proxy; curproxy; curproxy = curproxy->next) { struct switching_rule *rule; struct server_rule *srule; struct sticking_rule *mrule; struct tcp_rule *trule; - struct listener *listener; unsigned int next_id; int nbproc; @@ -6115,14 +6114,6 @@ int check_config_validity() } } - /* 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); @@ -7005,6 +6996,86 @@ out_uri_auth_compat: if (curproxy->options2 & PR_O2_RDPC_PRST) curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE; } + } + + /***********************************************************/ + /* At this point, target names have already been resolved. */ + /***********************************************************/ + + /* Check multi-process mode compatibility */ + + if (global.nbproc > 1 && global.stats_fe) { + list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) { + unsigned long mask; + + mask = nbits(global.nbproc); + if (global.stats_fe->bind_proc) + mask &= global.stats_fe->bind_proc; + + if (bind_conf->bind_proc) + mask &= bind_conf->bind_proc; + + /* stop here if more than one process is used */ + if (popcount(mask) > 1) + break; + } + if (&bind_conf->by_fe != &global.stats_fe->conf.bind) { + Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n"); + } + } + + /* Make each frontend inherit bind-process from its listeners when not specified. */ + for (curproxy = proxy; curproxy; curproxy = curproxy->next) { + if (curproxy->bind_proc) + continue; + + list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { + unsigned long mask; + + mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; + curproxy->bind_proc |= mask; + } + + if (!curproxy->bind_proc) + curproxy->bind_proc = ~0UL; + } + + if (global.stats_fe) { + list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) { + unsigned long mask; + + mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; + global.stats_fe->bind_proc |= mask; + } + if (!global.stats_fe->bind_proc) + global.stats_fe->bind_proc = ~0UL; + } + + /* propagate bindings from frontends to backends */ + for (curproxy = proxy; curproxy; curproxy = curproxy->next) { + if (curproxy->cap & PR_CAP_FE) + propagate_processes(curproxy, NULL); + } + + /* Bind each unbound backend to all processes when not specified. */ + for (curproxy = proxy; curproxy; curproxy = curproxy->next) { + if (curproxy->bind_proc) + continue; + curproxy->bind_proc = ~0UL; + } + + /*******************************************************/ + /* At this step, all proxies have a non-null bind_proc */ + /*******************************************************/ + + /* perform the final checks before creating tasks */ + + for (curproxy = proxy; curproxy; curproxy = curproxy->next) { + struct listener *listener; + unsigned int next_id; + int nbproc; + + nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc)); #ifdef USE_OPENSSL /* Configure SSL for each bind line. @@ -7149,71 +7220,6 @@ out_uri_auth_compat: curproxy->id); cfgerr++; } - - curproxy = curproxy->next; - } - - /* Check multi-process mode compatibility */ - if (global.nbproc > 1 && global.stats_fe) { - list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) { - unsigned long mask; - - mask = nbits(global.nbproc); - if (global.stats_fe->bind_proc) - mask &= global.stats_fe->bind_proc; - - if (bind_conf->bind_proc) - mask &= bind_conf->bind_proc; - - /* stop here if more than one process is used */ - if (popcount(mask) > 1) - break; - } - if (&bind_conf->by_fe != &global.stats_fe->conf.bind) { - Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n"); - } - } - - /* At this point, target names have already been resolved */ - - /* Make each frontend inherit bind-process from its listeners when not specified. */ - for (curproxy = proxy; curproxy; curproxy = curproxy->next) { - if (curproxy->bind_proc) - continue; - - list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { - unsigned long mask; - - mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; - curproxy->bind_proc |= mask; - } - - if (!curproxy->bind_proc) - curproxy->bind_proc = ~0UL; - } - - if (global.stats_fe) { - list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) { - unsigned long mask; - - mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL; - global.stats_fe->bind_proc |= mask; - } - if (!global.stats_fe->bind_proc) - global.stats_fe->bind_proc = ~0UL; - } - - /* propagate bindings from frontends to backends */ - for (curproxy = proxy; curproxy; curproxy = curproxy->next) { - if (curproxy->cap & PR_CAP_FE) - propagate_processes(curproxy, NULL); - } - - /* Bind each unbound backend to all processes when not specified. */ - for (curproxy = proxy; curproxy; curproxy = curproxy->next) { - if (curproxy->bind_proc) - continue; - curproxy->bind_proc = ~0UL; } /* automatically compute fullconn if not set. We must not do it in the -- 1.8.5.5