diff --git a/include/proto/backend.h b/include/proto/backend.h index a6f1c9f4d..c8322b8eb 100644 --- a/include/proto/backend.h +++ b/include/proto/backend.h @@ -1,23 +1,23 @@ /* - include/proto/backend.h - Functions prototypes for the backend. - - Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, version 2.1 - exclusively. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * include/proto/backend.h + * Functions prototypes for the backend. + * + * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #ifndef _PROTO_BACKEND_H #define _PROTO_BACKEND_H @@ -51,7 +51,7 @@ static inline int srv_is_usable(int state, int weight) { if (!weight) return 0; - if (state & SRV_GOINGDOWN) + if (state & (SRV_GOINGDOWN | SRV_MAINTAIN)) return 0; if (!(state & SRV_RUNNING)) return 0; diff --git a/src/cfgparse.c b/src/cfgparse.c index b881cd94d..4fed92e80 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6076,6 +6076,97 @@ out_uri_auth_compat: curproxy->lbprm.wmult = 1; /* default weight multiplier */ curproxy->lbprm.wdiv = 1; /* default weight divider */ + /* + * If this server supports a maxconn parameter, it needs a dedicated + * tasks to fill the emptied slots when a connection leaves. + * Also, resolve deferred tracking dependency if needed. + */ + newsrv = curproxy->srv; + while (newsrv != NULL) { + if (newsrv->minconn > newsrv->maxconn) { + /* Only 'minconn' was specified, or it was higher than or equal + * to 'maxconn'. Let's turn this into maxconn and clean it, as + * this will avoid further useless expensive computations. + */ + newsrv->maxconn = newsrv->minconn; + } else if (newsrv->maxconn && !newsrv->minconn) { + /* minconn was not specified, so we set it to maxconn */ + newsrv->minconn = newsrv->maxconn; + } + + if (newsrv->trackit) { + struct proxy *px; + struct server *srv; + char *pname, *sname; + + pname = newsrv->trackit; + sname = strrchr(pname, '/'); + + if (sname) + *sname++ = '\0'; + else { + sname = pname; + pname = NULL; + } + + if (pname) { + px = findproxy(pname, PR_CAP_BE); + if (!px) { + Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n", + proxy_type_str(curproxy), curproxy->id, + newsrv->id, pname); + cfgerr++; + goto next_srv; + } + } else + px = curproxy; + + srv = findserver(px, sname); + if (!srv) { + Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n", + proxy_type_str(curproxy), curproxy->id, + newsrv->id, sname); + cfgerr++; + goto next_srv; + } + + if (!(srv->state & SRV_CHECKED)) { + Alert("config : %s '%s', server '%s': unable to use %s/%s for " + "tracking as it does not have checks enabled.\n", + proxy_type_str(curproxy), curproxy->id, + newsrv->id, px->id, srv->id); + cfgerr++; + goto next_srv; + } + + if (curproxy != px && + (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) { + Alert("config : %s '%s', server '%s': unable to use %s/%s for" + "tracking: disable-on-404 option inconsistency.\n", + proxy_type_str(curproxy), curproxy->id, + newsrv->id, px->id, srv->id); + cfgerr++; + goto next_srv; + } + + /* if the other server is forced disabled, we have to do the same here */ + if (srv->state & SRV_MAINTAIN) { + newsrv->state |= SRV_MAINTAIN; + newsrv->state &= ~SRV_RUNNING; + newsrv->health = 0; + } + + newsrv->track = srv; + newsrv->tracknext = srv->tracknext; + srv->tracknext = newsrv; + + free(newsrv->trackit); + newsrv->trackit = NULL; + } + next_srv: + newsrv = newsrv->next; + } + /* We have to initialize the server lookup mechanism depending * on what LB algorithm was choosen. */ @@ -6208,89 +6299,6 @@ out_uri_auth_compat: newsrv = newsrv->next; } - /* - * If this server supports a maxconn parameter, it needs a dedicated - * tasks to fill the emptied slots when a connection leaves. - * Also, resolve deferred tracking dependency if needed. - */ - newsrv = curproxy->srv; - while (newsrv != NULL) { - if (newsrv->minconn > newsrv->maxconn) { - /* Only 'minconn' was specified, or it was higher than or equal - * to 'maxconn'. Let's turn this into maxconn and clean it, as - * this will avoid further useless expensive computations. - */ - newsrv->maxconn = newsrv->minconn; - } else if (newsrv->maxconn && !newsrv->minconn) { - /* minconn was not specified, so we set it to maxconn */ - newsrv->minconn = newsrv->maxconn; - } - - if (newsrv->trackit) { - struct proxy *px; - struct server *srv; - char *pname, *sname; - - pname = newsrv->trackit; - sname = strrchr(pname, '/'); - - if (sname) - *sname++ = '\0'; - else { - sname = pname; - pname = NULL; - } - - if (pname) { - px = findproxy(pname, PR_CAP_BE); - if (!px) { - Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n", - proxy_type_str(curproxy), curproxy->id, - newsrv->id, pname); - cfgerr++; - goto next_srv; - } - } else - px = curproxy; - - srv = findserver(px, sname); - if (!srv) { - Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n", - proxy_type_str(curproxy), curproxy->id, - newsrv->id, sname); - cfgerr++; - goto next_srv; - } - - if (!(srv->state & SRV_CHECKED)) { - Alert("config : %s '%s', server '%s': unable to use %s/%s for " - "tracking as it does not have checks enabled.\n", - proxy_type_str(curproxy), curproxy->id, - newsrv->id, px->id, srv->id); - cfgerr++; - goto next_srv; - } - - if (curproxy != px && - (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) { - Alert("config : %s '%s', server '%s': unable to use %s/%s for" - "tracking: disable-on-404 option inconsistency.\n", - proxy_type_str(curproxy), curproxy->id, - newsrv->id, px->id, srv->id); - cfgerr++; - goto next_srv; - } - - newsrv->track = srv; - newsrv->tracknext = srv->tracknext; - srv->tracknext = newsrv; - - free(newsrv->trackit); - } - next_srv: - newsrv = newsrv->next; - } - if (curproxy->cap & PR_CAP_FE) { curproxy->accept = frontend_accept;