]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] add support for time units in the configuration
authorWilly Tarreau <w@1wt.eu>
Sun, 2 Dec 2007 21:15:14 +0000 (22:15 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Dec 2007 21:15:14 +0000 (22:15 +0100)
It is not always handy to manipulate large values exprimed
in milliseconds for timeouts. Also, some values are entered
in seconds (such as the stats refresh interval). This patch
adds support for time units. It knows about 'us', 'ms', 's',
'm', 'h', and 'd'. It automatically converts each value into
the caller's expected unit. Unit-less values are still passed
unchanged.

The unit must be passed as a suffix to the number. For instance:

     clitimeout 15m

If any character is not understood, an error is returned.

src/cfgparse.c
src/dumpstats.c
tests/test-time.cfg [new file with mode: 0644]

index b64d4c6b47f56d9c6d019f43a0b5b059fb2b959d..4ebb9ff178de3b24c18a3134e253c3639f9bc5c3 100644 (file)
@@ -513,7 +513,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
        static struct proxy *curproxy = NULL;
        struct server *newsrv = NULL;
        const char *err;
-       int rc, val;
+       int rc;
+       unsigned val;
 
        if (!strcmp(args[0], "listen"))
                rc = PR_CAP_LISTEN;
@@ -868,7 +869,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                curproxy->appsession_name = strdup(args[1]);
                curproxy->appsession_name_len = strlen(curproxy->appsession_name);
                curproxy->appsession_len = atoi(args[3]);
-               val = atoi(args[5]);
+               err = parse_time_err(args[5], &val, TIME_UNIT_MS);
+               if (err) {
+                       Alert("parsing [%s:%d] : unexpected character '%c' in %s timeout.\n",
+                             file, linenum, *err, args[0]);
+                       return -1;
+               }
                if (val > 0)
                        __tv_from_ms(&curproxy->appsession_timeout, val);
                else
@@ -977,7 +983,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                              file, linenum, args[0]);
                        return -1;
                }
-               val = atoi(args[1]);
+               err = parse_time_err(args[1], &val, TIME_UNIT_MS);
+               if (err) {
+                       Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
+                             file, linenum, *err, args[0]);
+                       return -1;
+               }
                if (val > 0)
                        __tv_from_ms(&curproxy->contimeout, val);
                else
@@ -997,7 +1008,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                              file, linenum, args[0]);
                        return -1;
                }
-               val = atoi(args[1]);
+               err = parse_time_err(args[1], &val, TIME_UNIT_MS);
+               if (err) {
+                       Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
+                             file, linenum, *err, args[0]);
+                       return -1;
+               }
                if (val > 0)
                        __tv_from_ms(&curproxy->clitimeout, val);
                else
@@ -1016,7 +1032,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                              file, linenum, args[0]);
                        return -1;
                }
-               val = atoi(args[1]);
+               err = parse_time_err(args[1], &val, TIME_UNIT_MS);
+               if (err) {
+                       Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
+                             file, linenum, *err, args[0]);
+                       return -1;
+               }
                if (val > 0)
                        __tv_from_ms(&curproxy->srvtimeout, val);
                else
@@ -1118,10 +1139,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                                return -1;
                        }
                } else if (!strcmp(args[1], "refresh")) {
-                       int interval = atoi(args[2]);
-                       
-                       if (interval < 0) {
-                               Alert("parsing [%s:%d] : 'refresh' needs a positive interval in seconds.\n", file, linenum);
+                       unsigned interval;
+
+                       err = parse_time_err(args[2], &interval, TIME_UNIT_S);
+                       if (err) {
+                               Alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
+                                     file, linenum, *err);
                                return -1;
                        } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
@@ -1383,7 +1406,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                        Alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
                        return -1;
                }
-               curproxy->grace = atol(args[1]);
+               err = parse_time_err(args[1], &val, TIME_UNIT_MS);
+               if (err) {
+                       Alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
+                             file, linenum, *err);
+                       return -1;
+               }
+               curproxy->grace = val;
        }
        else if (!strcmp(args[0], "dispatch")) {  /* dispatch address */
                if (curproxy == &defproxy) {
@@ -1502,7 +1531,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                                cur_arg += 2;
                        }
                        else if (!strcmp(args[cur_arg], "inter")) {
-                               newsrv->inter = atol(args[cur_arg + 1]);
+                               const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
+                               if (err) {
+                                       Alert("parsing [%s:%d] : unexpected character '%c' in 'inter' argument of server %s.\n",
+                                             file, linenum, *err, newsrv->id);
+                                       return -1;
+                               }
+                               newsrv->inter = val;
                                cur_arg += 2;
                        }
                        else if (!strcmp(args[cur_arg], "addr")) {
@@ -1542,7 +1577,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                        }
                        else if (!strcmp(args[cur_arg], "slowstart")) {
                                /* slowstart is stored in seconds */
-                               newsrv->slowstart = (atol(args[cur_arg + 1]) + 999) / 1000;
+                               const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_S);
+                               if (err) {
+                                       Alert("parsing [%s:%d] : unexpected character '%c' in 'slowstart' argument of server %s.\n",
+                                             file, linenum, *err, newsrv->id);
+                                       return -1;
+                               }
+                               newsrv->slowstart = val;
                                cur_arg += 2;
                        }
                        else if (!strcmp(args[cur_arg], "check")) {
index 7454600f4b73bfc0a4a03f1df1a3da0bd055ba21..9531773f7f7bf01c6584e2330c05dbaf96c5bd8c 100644 (file)
@@ -127,9 +127,15 @@ int stats_parse_global(const char **args, char *err, int errlen)
                global.maxsock++;
        }
        else if (!strcmp(args[0], "timeout")) {
-               int timeout = atol(args[1]);
+               unsigned timeout;
+               const char *res = parse_time_err(args[1], &timeout, TIME_UNIT_MS);
 
-               if (timeout <= 0) {
+               if (res) {
+                       snprintf(err, errlen, "unexpected character '%c' in 'stats timeout' in 'global' section", *res);
+                       return -1;
+               }
+
+               if (!timeout) {
                        snprintf(err, errlen, "a positive value is expected for 'stats timeout' in 'global section'");
                        return -1;
                }
diff --git a/tests/test-time.cfg b/tests/test-time.cfg
new file mode 100644 (file)
index 0000000..6999653
--- /dev/null
@@ -0,0 +1,24 @@
+# This is a test configuration.
+# It is used to check that time units are correctly parsed.
+
+global
+       maxconn    1000
+        stats timeout 3s
+
+listen  sample1
+        mode       http
+        retries    1
+        redispatch
+        contimeout 5s
+        clitimeout 15m
+        srvtimeout 15m
+        maxconn    40000
+        bind       :8080
+        balance    roundrobin
+       option     allbackups
+        server     act1 127.0.0.1:80 weight 10 check port 81 inter 500ms fall 1
+        server     act2 127.0.0.2:80 weight 20 check port 81 inter 500ms fall 1
+        server     act3 127.0.0.3:80 weight 30 check port 81 inter 500ms fall 1
+        option     httpclose
+       stats      uri /stats
+       stats      refresh 5000ms