]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] config: split parser and checker in two functions
authorWilly Tarreau <w@1wt.eu>
Mon, 22 Jun 2009 13:48:36 +0000 (15:48 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 23 Jun 2009 06:17:17 +0000 (08:17 +0200)
This is a first step towards support of multiple configuration files.
Now readcfgfile() only reads a file in memory and performs very minimal
parsing. The checks are performed afterwards.

include/common/cfgparse.h
include/proto/proxy.h
src/cfgparse.c
src/haproxy.c
src/proxy.c

index 35e5614e947cd5aee81552c2e617a69b4837dba6..3b376a09f31843d83f318188d29ff56556105c06 100644 (file)
@@ -64,6 +64,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv);
 int readcfgfile(const char *file);
 void cfg_register_keywords(struct cfg_kw_list *kwl);
 void cfg_unregister_keywords(struct cfg_kw_list *kwl);
+void init_default_instance();
+int check_config_validity();
 
 #endif /* _COMMON_CFGPARSE_H */
 
index adb16cef4db5af7776cc0ab612e93d47c947cd4b..8a2789df1ee706593c71c3bfb7ec18fd539a1b7d 100644 (file)
@@ -40,7 +40,7 @@ const char *proxy_cap_str(int cap);
 const char *proxy_mode_str(int mode);
 struct proxy *findproxy(const char *name, int mode, int cap);
 struct server *findserver(const struct proxy *px, const char *name);
-int proxy_cfg_ensure_no_http(struct proxy *curproxy, const char *file);
+int proxy_cfg_ensure_no_http(struct proxy *curproxy);
 
 /*
  * This function returns a string containing the type of the proxy in a format
index 6c0065145c3b494e8d3a61ab7346ba5dcf095017..ce6b266b892852c8c7694065e809fcf98c5b28e0 100644 (file)
@@ -672,7 +672,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
 }
 
 
-static void init_default_instance()
+void init_default_instance()
 {
        memset(&defproxy, 0, sizeof(defproxy));
        defproxy.mode = PR_MODE_TCP;
@@ -3222,17 +3222,11 @@ int readcfgfile(const char *file)
        char thisline[LINESIZE];
        FILE *f;
        int linenum = 0;
-       int cfgerr = 0;
        int confsect = CFG_NONE;
 
-       struct proxy *curproxy = NULL;
-       struct server *newsrv = NULL;
-
        if ((f=fopen(file,"r")) == NULL)
                return -1;
 
-       init_default_instance();
-
        while (fgets(thisline, sizeof(thisline), f) != NULL) {
                int arg, kwm = KWM_STD;
                char *end;
@@ -3380,6 +3374,18 @@ int readcfgfile(const char *file)
        free(cursection);
        cursection = NULL;
        fclose(f);
+       return 0;
+ err:
+       free(cursection);
+       cursection = NULL;
+       return -1;
+}
+
+int check_config_validity()
+{
+       int cfgerr = 0;
+       struct proxy *curproxy = NULL;
+       struct server *newsrv = NULL;
 
        /*
         * Now, check for the integrity of all that we have collected.
@@ -3402,8 +3408,7 @@ int readcfgfile(const char *file)
        }
 
        if ((curproxy = proxy) == NULL) {
-               Alert("parsing %s : no <listen> line. Nothing to do !\n",
-                     file);
+               Alert("config : no <listen> line. Nothing to do !\n");
                goto err;
        }
 
@@ -3420,54 +3425,54 @@ int readcfgfile(const char *file)
 
                switch (curproxy->mode) {
                case PR_MODE_HEALTH:
-                       cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
+                       cfgerr += proxy_cfg_ensure_no_http(curproxy);
                        if (!(curproxy->cap & PR_CAP_FE)) {
-                               Alert("parsing %s : %s '%s' cannot be in health mode as it has no frontend capability.\n",
-                                     file, proxy_type_str(curproxy), curproxy->id);
+                               Alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
+                                     proxy_type_str(curproxy), curproxy->id);
                                cfgerr++;
                        }
 
                        if (curproxy->srv != NULL)
-                               Warning("parsing %s : servers will be ignored for %s '%s'.\n",
-                                       file, proxy_type_str(curproxy), curproxy->id);
+                               Warning("config : servers will be ignored for %s '%s'.\n",
+                                       proxy_type_str(curproxy), curproxy->id);
                        break;
 
                case PR_MODE_TCP:
-                       cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
+                       cfgerr += proxy_cfg_ensure_no_http(curproxy);
                        break;
 
                case PR_MODE_HTTP:
                        if ((curproxy->cookie_name != NULL) && (curproxy->srv == NULL)) {
-                               Alert("parsing %s : HTTP proxy %s has a cookie but no server list !\n",
-                                     file, curproxy->id);
+                               Alert("config : HTTP proxy %s has a cookie but no server list !\n",
+                                     curproxy->id);
                                cfgerr++;
                        }
                        break;
                }
 
                if ((curproxy->cap & PR_CAP_FE) && (curproxy->listen == NULL))  {
-                       Alert("parsing %s : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
-                             file, proxy_type_str(curproxy), curproxy->id);
+                       Alert("config : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
+                             proxy_type_str(curproxy), curproxy->id);
                        cfgerr++;
                }
 
                if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
                        if (curproxy->lbprm.algo & BE_LB_ALGO) {
                                if (curproxy->options & PR_O_TRANSP) {
-                                       Alert("parsing %s : %s '%s' cannot use both transparent and balance mode.\n",
-                                             file, proxy_type_str(curproxy), curproxy->id);
+                                       Alert("config : %s '%s' cannot use both transparent and balance mode.\n",
+                                             proxy_type_str(curproxy), curproxy->id);
                                        cfgerr++;
                                }
 #ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
                                else if (curproxy->srv == NULL) {
-                                       Alert("parsing %s : %s '%s' needs at least 1 server in balance mode.\n",
-                                             file, proxy_type_str(curproxy), curproxy->id);
+                                       Alert("config : %s '%s' needs at least 1 server in balance mode.\n",
+                                             proxy_type_str(curproxy), curproxy->id);
                                        cfgerr++;
                                }
 #endif
                                else if (*(int *)&curproxy->dispatch_addr.sin_addr != 0) {
-                                       Warning("parsing %s : dispatch address of %s '%s' will be ignored in balance mode.\n",
-                                               file, proxy_type_str(curproxy), curproxy->id);
+                                       Warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
+                                               proxy_type_str(curproxy), curproxy->id);
                                }
                        }
                        else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
@@ -3483,8 +3488,8 @@ int readcfgfile(const char *file)
 
                if ((curproxy->options & PR_O_DISABLE404) && !(curproxy->options & PR_O_HTTP_CHK)) {
                        curproxy->options &= ~PR_O_DISABLE404;
-                       Warning("parsing %s : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
-                               file, "disable-on-404", proxy_type_str(curproxy), curproxy->id);
+                       Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
+                               "disable-on-404", proxy_type_str(curproxy), curproxy->id);
                }
 
                /* if a default backend was specified, let's find it */
@@ -3570,11 +3575,11 @@ int readcfgfile(const char *file)
                    (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
                     ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
                      (!curproxy->timeout.connect || !curproxy->timeout.server)))) {
-                       Warning("parsing %s : missing timeouts for %s '%s'.\n"
+                       Warning("config : missing timeouts for %s '%s'.\n"
                                "   | While not properly invalid, you will certainly encounter various problems\n"
                                "   | with such a configuration. To fix this, please ensure that all following\n"
                                "   | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
-                               file, proxy_type_str(curproxy), curproxy->id);
+                               proxy_type_str(curproxy), curproxy->id);
                }
 
                /* Historically, the tarpit and queue timeouts were inherited from contimeout.
@@ -3669,8 +3674,8 @@ int readcfgfile(const char *file)
                newsrv = curproxy->srv;
                while (newsrv != NULL) {
                        if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
-                               Alert("parsing [%s:%d] : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
-                                     file, linenum, proxy_type_str(curproxy), curproxy->id);
+                               Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
+                                     proxy_type_str(curproxy), curproxy->id);
                                goto err;
                        }
                        newsrv = newsrv->next;
@@ -3693,8 +3698,8 @@ int readcfgfile(const char *file)
                                /* minconn was not specified, so we set it to maxconn */
                                newsrv->minconn = newsrv->maxconn;
                        } else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
-                               Alert("parsing [%s:%d] : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
-                                     file, linenum, proxy_type_str(curproxy), curproxy->id);
+                               Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
+                                     proxy_type_str(curproxy), curproxy->id);
                                goto err;
                        }
 
@@ -3716,8 +3721,8 @@ int readcfgfile(const char *file)
                                if (pname) {
                                        px = findproxy(pname, curproxy->mode, PR_CAP_BE);
                                        if (!px) {
-                                               Alert("parsing %s, %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
-                                                       file, proxy_type_str(curproxy), curproxy->id,
+                                               Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
+                                                       proxy_type_str(curproxy), curproxy->id,
                                                        newsrv->id, pname);
                                                return -1;
                                        }
@@ -3726,25 +3731,25 @@ int readcfgfile(const char *file)
 
                                srv = findserver(px, sname);
                                if (!srv) {
-                                       Alert("parsing %s, %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
-                                               file, proxy_type_str(curproxy), curproxy->id,
+                                       Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
+                                               proxy_type_str(curproxy), curproxy->id,
                                                newsrv->id, sname);
                                        return -1;
                                }
 
                                if (!(srv->state & SRV_CHECKED)) {
-                                       Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for "
+                                       Alert("config : %s '%s', server '%s': unable to use %s/%s for "
                                                "tracing as it does not have checks enabled.\n",
-                                               file, proxy_type_str(curproxy), curproxy->id,
+                                               proxy_type_str(curproxy), curproxy->id,
                                                newsrv->id, px->id, srv->id);
                                        return -1;
                                }
 
                                if (curproxy != px &&
                                        (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
-                                       Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for"
+                                       Alert("config : %s '%s', server '%s': unable to use %s/%s for"
                                                "tracing: disable-on-404 option inconsistency.\n",
-                                               file, proxy_type_str(curproxy), curproxy->id,
+                                               proxy_type_str(curproxy), curproxy->id,
                                                newsrv->id, px->id, srv->id);
                                        return -1;
                                }
@@ -3791,7 +3796,7 @@ int readcfgfile(const char *file)
        }
 
        if (cfgerr > 0) {
-               Alert("Errors found in configuration file, aborting.\n");
+               Alert("Errors found in configuration, aborting.\n");
                goto err;
        }
 
@@ -3811,13 +3816,8 @@ int readcfgfile(const char *file)
                                global.last_checks |= cfg_opts2[optnum].checks;
        }
 
-       free(cursection);
-       cursection = NULL;
        return 0;
-
  err:
-       free(cursection);
-       cursection = NULL;
        return -1;
 }
 
index 68c8b4b4722aa193b3804a2d5b8429bc981d8c60..aac8ac16171405b4b5d9af251c494d4572a3eee0 100644 (file)
@@ -529,19 +529,27 @@ void init(int argc, char **argv)
 
        have_appsession = 0;
        global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
+
+       init_default_instance();
+
        if (readcfgfile(cfg_cfgfile) < 0) {
                Alert("Error reading configuration file : %s\n", cfg_cfgfile);
                exit(1);
        }
 
-       if (have_appsession)
-               appsession_init();
+       if (check_config_validity() < 0) {
+               Alert("Errors found in configuration.\n");
+               exit(1);
+       }
 
        if (global.mode & MODE_CHECK) {
-               qfprintf(stdout, "Configuration file is valid : %s\n", cfg_cfgfile);
+               qfprintf(stdout, "Configuration file is valid\n");
                exit(0);
        }
 
+       if (have_appsession)
+               appsession_init();
+
        if (start_checks() < 0)
                exit(1);
 
index b3b33d4829c79dd8fed5edee50d1232d8981e1c9..69b070e2b4c195000ad6ce04728516b6a81717f2 100644 (file)
@@ -303,29 +303,29 @@ struct server *findserver(const struct proxy *px, const char *name) {
  * at the end of the configuration parsing if the proxy is not in http mode.
  * The <file> argument is used to construct the error message.
  */
-int proxy_cfg_ensure_no_http(struct proxy *curproxy, const char *file)
+int proxy_cfg_ensure_no_http(struct proxy *curproxy)
 {
        if (curproxy->cookie_name != NULL) {
-               Warning("parsing %s : cookie will be ignored for %s '%s' (needs 'mode http').\n",
-                       file, proxy_type_str(curproxy), curproxy->id);
+               Warning("config : cookie will be ignored for %s '%s' (needs 'mode http').\n",
+                       proxy_type_str(curproxy), curproxy->id);
        }
        if (curproxy->rsp_exp != NULL) {
-               Warning("parsing %s : server regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
-                       file, proxy_type_str(curproxy), curproxy->id);
+               Warning("config : server regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
+                       proxy_type_str(curproxy), curproxy->id);
        }
        if (curproxy->req_exp != NULL) {
-               Warning("parsing %s : client regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
-                       file, proxy_type_str(curproxy), curproxy->id);
+               Warning("config : client regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
+                       proxy_type_str(curproxy), curproxy->id);
        }
        if (curproxy->monitor_uri != NULL) {
-               Warning("parsing %s : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n",
-                       file, proxy_type_str(curproxy), curproxy->id);
+               Warning("config : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n",
+                       proxy_type_str(curproxy), curproxy->id);
        }
        if (curproxy->lbprm.algo & BE_LB_PROP_L7) {
                curproxy->lbprm.algo &= ~BE_LB_ALGO;
                curproxy->lbprm.algo |= BE_LB_ALGO_RR;
-               Warning("parsing %s : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
-                       file, proxy_type_str(curproxy), curproxy->id);
+               Warning("config : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
+                       proxy_type_str(curproxy), curproxy->id);
        }
        return 0;
 }