[MEDIUM] implemented the "default_backend" keyword

The "default_backend" keyword used in a frontend sets the
default backend which will be used if no setbe rule matches.
This commit is contained in:
Willy Tarreau 2007-01-01 23:11:07 +01:00
parent 128e954663
commit 5fdfb911a0
3 changed files with 65 additions and 1 deletions

View File

@ -76,6 +76,10 @@ struct proxy {
int state; /* proxy state */
struct sockaddr_in dispatch_addr; /* the default address to connect to */
struct proxy *fiprm, *beprm; /* proxy we find filter and backend params from (default: self) */
union {
struct proxy *be; /* default backend, or NULL if none set */
char *name; /* default backend name during config parse */
} defbe;
struct server *srv; /* known servers */
int srv_act, srv_bck; /* # of running servers */
int tot_wact, tot_wbck; /* total weights of active and backup servers */

View File

@ -501,6 +501,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
if (defproxy.monitor_uri)
curproxy->monitor_uri = strdup(defproxy.monitor_uri);
curproxy->monitor_uri_len = defproxy.monitor_uri_len;
if (defproxy.defbe.name)
curproxy->defbe.name = strdup(defproxy.defbe.name);
}
if (curproxy->cap & PR_CAP_BE) {
@ -522,10 +524,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
}
else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
/* some variables may have already been initialized earlier */
/* FIXME-20070101: we should do this too at the end of the
* config parsing to free all default values.
*/
if (defproxy.check_req) free(defproxy.check_req);
if (defproxy.cookie_name) free(defproxy.cookie_name);
if (defproxy.capture_name) free(defproxy.capture_name);
if (defproxy.monitor_uri) free(defproxy.monitor_uri);
if (defproxy.defbe.name) free(defproxy.defbe.name);
for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
if (defproxy.errmsg[rc].len)
@ -981,6 +987,18 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
}
return 0;
}
else if (!strcmp(args[0], "default_backend")) {
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
return 0;
if (*(args[1]) == 0) {
Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
return -1;
}
if (curproxy->defbe.name)
free(curproxy->defbe.name);
curproxy->defbe.name = strdup(args[1]);
}
else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
return 0;
@ -2103,6 +2121,36 @@ int readcfgfile(const char *file)
}
}
/* if a default backend was specified, let's find it */
if (curproxy->defbe.name) {
struct proxy *target;
for (target = proxy; target != NULL; target = target->next) {
if (strcmp(target->id, curproxy->defbe.name) == 0)
break;
}
if (target == NULL) {
Alert("parsing %s : default backend '%s' in HTTP %s '%s' was not found !\n",
file, curproxy->defbe.name, proxy_type_str(curproxy), curproxy->id);
cfgerr++;
} else if (target == curproxy) {
Alert("parsing %s : loop detected for default backend %s !\n", file, curproxy->defbe.name);
cfgerr++;
} else if (!(target->cap & PR_CAP_BE)) {
Alert("parsing %s : default backend '%s' in HTTP %s '%s' has no backend capability !\n",
file, curproxy->defbe.name, proxy_type_str(curproxy), curproxy->id);
cfgerr++;
} else if (target->mode != curproxy->mode) {
Alert("parsing %s : default backend '%s' in HTTP %s '%s' is not of same mode (tcp/http) !\n",
file, curproxy->defbe.name, proxy_type_str(curproxy), curproxy->id);
cfgerr++;
} else {
free(curproxy->defbe.name);
curproxy->defbe.be = target;
}
}
/* find the target proxy in setbe */
if (curproxy->mode == PR_MODE_HTTP && curproxy->req_exp != NULL) {
/* map jump target for ACT_SETBE in req_rep chain */
struct hdr_exp *exp;

View File

@ -1087,7 +1087,19 @@ int process_cli(struct session *t)
return 1;
}
} while (cur_proxy != t->be); /* we loop only if t->be has changed */
if (!(t->flags & SN_BE_ASSIGNED) && cur_proxy->defbe.be) {
/* No backend was set, but there was a default
* backend set in the frontend, so we use it and
* loop again.
*/
t->be = cur_proxy->defbe.be;
t->be->beprm->beconn++;
if (t->be->beprm->beconn > t->be->beprm->beconn_max)
t->be->beprm->beconn_max = t->be->beprm->beconn;
t->be->beprm->cum_beconn++;
t->flags |= SN_BE_ASSIGNED;
}
} while (t->be != cur_proxy); /* we loop only if t->be has changed */
if (!(t->flags & SN_BE_ASSIGNED)) {