]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] implemented the "default_backend" keyword
authorWilly Tarreau <w@1wt.eu>
Mon, 1 Jan 2007 22:11:07 +0000 (23:11 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 1 Jan 2007 22:11:07 +0000 (23:11 +0100)
The "default_backend" keyword used in a frontend sets the
default backend which will be used if no setbe rule matches.

include/types/proxy.h
src/cfgparse.c
src/proto_http.c

index d710be8d55a42fc6b42f42c15dbbf2a7e779f5c9..71f0f5c2acdebae20fa26949ed76dfab917fbe69 100644 (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 */
index 9589841980c80f1895f0478629e5d16f9ec0484f..38d894a7ddcc5cc6a689f2f1461a8113c6a8943b 100644 (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;
index 75fd1525af2c2d2052eceb461e3faa49f59e3735..0202ba2263a3b0809b33323152d3bb79b92fb319 100644 (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)) {