]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: log: Keep the ref when a log server is copied to avoid duplicate entries
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 26 Mar 2018 14:09:19 +0000 (16:09 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 5 Apr 2018 13:13:54 +0000 (15:13 +0200)
With "log global" line, the global list of loggers are copied into the proxy's
struct. The list coming from the default section is also copied when a frontend
or a backend section is parsed. So it is possible to have duplicate entries in
the proxy's list. For instance, with this following config, all messages will be
logged twice:

    global
        log 127.0.0.1 local0 debug
        daemon

    defaults
        mode   http
        log    global
        option httplog

    frontend front-http
        log global
        bind *:8888
        default_backend back-http

    backend back-http
        server www 127.0.0.1:8000

include/types/log.h
src/cfgparse.c
src/log.c

index 0fdb775771030651f40717abba6adae80ac1308f..c394d773456ec31748506aed6c76f5da49c6c967 100644 (file)
@@ -175,6 +175,7 @@ struct logsrv {
        int level;
        int minlvl;
        int maxlen;
+       struct logsrv *ref;
 };
 
 #endif /* _TYPES_LOG_H */
index 6100f86ac390d600a0e6988e08b8a87fad95f3e2..37bbf45313299ed44f4a53747458040f02b348d1 100644 (file)
@@ -2836,6 +2836,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
                        struct logsrv *node = malloc(sizeof(*node));
                        memcpy(node, tmplogsrv, sizeof(struct logsrv));
+                       node->ref = tmplogsrv->ref;
                        LIST_INIT(&node->list);
                        LIST_ADDQ(&curproxy->logsrvs, &node->list);
                }
index 1be6dccee33fd187f45f4f549769815f90ad2a12..b2d4367f4d00a2bed07b2a30d8c6c62b144b1155 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -720,10 +720,21 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err)
                        goto error;
                }
                list_for_each_entry(logsrv, &global.logsrvs, list) {
-                       struct logsrv *node = malloc(sizeof(*node));
+                       struct logsrv *node;
+
+                       list_for_each_entry(node, logsrvs, list) {
+                               if (node->ref == logsrv)
+                                       goto skip_logsrv;
+                       }
+
+                       node = malloc(sizeof(*node));
                        memcpy(node, logsrv, sizeof(struct logsrv));
+                       node->ref = logsrv;
                        LIST_INIT(&node->list);
                        LIST_ADDQ(logsrvs, &node->list);
+
+                 skip_logsrv:
+                       continue;
                }
                return 1;
        }