]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: peers: peer synchronization issue (with several peers sections).
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 13 Jul 2017 07:07:09 +0000 (09:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Jul 2017 07:39:29 +0000 (09:39 +0200)
When several stick-tables were configured with several peers sections,
only a part of them could be synchronized: the ones attached to the last
parsed 'peers' section. This was due to the fact that, at least, the peer I/O handler
refered to the wrong peer section list, in fact always the same: the last one parsed.

The fact that the global peer section list was named "struct peers *peers"
lead to this issue. This variable name is dangerous ;).

So this patch renames global 'peers' variable to 'cfg_peers' to ensure that
no such wrong references are still in use, then all the functions wich used
old 'peers' variable have been modified to refer to the correct peer list.

Must be backported to 1.6 and 1.7.

include/types/peers.h
src/cfgparse.c
src/haproxy.c
src/peers.c
src/proxy.c

index 105dffb04bac7c01b88b5fb5710985b2bfc98a48..a77a0942b4ee3c17e89be83ee43460808136d04e 100644 (file)
@@ -91,7 +91,7 @@ struct peers {
 };
 
 
-extern struct peers *peers;
+extern struct peers *cfg_peers;
 
 #endif /* _TYPES_PEERS_H */
 
index 600f2737d51f9f851f53c7eec0bbce304b7535be..ecd4c9f3af83d3eeb7ff1d01a99c7f50ad0278f2 100644 (file)
@@ -1941,7 +1941,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               for (curpeers = peers; curpeers != NULL; curpeers = curpeers->next) {
+               for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
                        /*
                         * If there are two proxies with the same name only following
                         * combinations are allowed:
@@ -1959,8 +1959,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               curpeers->next = peers;
-               peers = curpeers;
+               curpeers->next = cfg_peers;
+               cfg_peers = curpeers;
                curpeers->conf.file = strdup(file);
                curpeers->conf.line = linenum;
                curpeers->last_change = now.tv_sec;
@@ -2040,7 +2040,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                if (strcmp(newpeer->id, localpeer) == 0) {
                        /* Current is local peer, it define a frontend */
                        newpeer->local = 1;
-                       peers->local = newpeer;
+                       cfg_peers->local = newpeer;
 
                        if (!curpeers->peers_fe) {
                                if ((curpeers->peers_fe  = calloc(1, sizeof(struct proxy))) == NULL) {
@@ -8087,9 +8087,9 @@ int check_config_validity()
                }
 
                if (curproxy->table.peers.name) {
-                       struct peers *curpeers = peers;
+                       struct peers *curpeers;
 
-                       for (curpeers = peers; curpeers; curpeers = curpeers->next) {
+                       for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
                                if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
                                        free((void *)curproxy->table.peers.name);
                                        curproxy->table.peers.p = curpeers;
@@ -9108,15 +9108,15 @@ out_uri_auth_compat:
                if (curproxy->table.peers.p)
                        curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
 
-       if (peers) {
-               struct peers *curpeers = peers, **last;
+       if (cfg_peers) {
+               struct peers *curpeers = cfg_peers, **last;
                struct peer *p, *pb;
 
                /* Remove all peers sections which don't have a valid listener,
                 * which are not used by any table, or which are bound to more
                 * than one process.
                 */
-               last = &peers;
+               last = &cfg_peers;
                while (*last) {
                        curpeers = *last;
 
index a42574433411f88f7c8d256114256baf15265740..23161007f184500ad716c9d2d1752175a8199ac3 100644 (file)
@@ -1448,7 +1448,7 @@ static void init(int argc, char **argv)
                struct peers *pr;
                struct proxy *px;
 
-               for (pr = peers; pr; pr = pr->next)
+               for (pr = cfg_peers; pr; pr = pr->next)
                        if (pr->peers_fe)
                                break;
 
@@ -1662,11 +1662,11 @@ static void init(int argc, char **argv)
        if (global.stats_fe)
                global.maxsock += global.stats_fe->maxconn;
 
-       if (peers) {
+       if (cfg_peers) {
                /* peers also need to bypass global maxconn */
-               struct peers *p = peers;
+               struct peers *p = cfg_peers;
 
-               for (p = peers; p; p = p->next)
+               for (p = cfg_peers; p; p = p->next)
                        if (p->peers_fe)
                                global.maxsock += p->peers_fe->maxconn;
        }
@@ -2653,7 +2653,7 @@ int main(int argc, char **argv)
                }
 
                /* we might have to unbind some peers sections from some processes */
-               for (curpeers = peers; curpeers; curpeers = curpeers->next) {
+               for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
                        if (!curpeers->peers_fe)
                                continue;
 
index 9847cbd0f82caadbf70062e2eb7911b4777ff0ba..f176d2441883970ebc2a4da33ab9fc14cdfad863 100644 (file)
@@ -171,7 +171,7 @@ enum {
 #define PEER_MINOR_VER        1
 #define PEER_DWNGRD_MINOR_VER 0
 
-struct peers *peers = NULL;
+struct peers *cfg_peers = NULL;
 static void peer_session_forceshutdown(struct appctx *appctx);
 
 /* This function encode an uint64 to 'dynamic' length format.
@@ -743,19 +743,19 @@ switchstate:
                                /* if current peer is local */
                                 if (curpeer->local) {
                                         /* if current host need resyncfrom local and no process assined  */
-                                        if ((peers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMLOCAL &&
-                                            !(peers->flags & PEERS_F_RESYNC_ASSIGN)) {
+                                        if ((curpeers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMLOCAL &&
+                                            !(curpeers->flags & PEERS_F_RESYNC_ASSIGN)) {
                                                 /* assign local peer for a lesson, consider lesson already requested */
                                                 curpeer->flags |= PEER_F_LEARN_ASSIGN;
-                                                peers->flags |= (PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
+                                                curpeers->flags |= (PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
                                         }
 
                                 }
-                                else if ((peers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMREMOTE &&
-                                         !(peers->flags & PEERS_F_RESYNC_ASSIGN)) {
+                                else if ((curpeers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMREMOTE &&
+                                         !(curpeers->flags & PEERS_F_RESYNC_ASSIGN)) {
                                         /* assign peer for a lesson  */
                                         curpeer->flags |= PEER_F_LEARN_ASSIGN;
-                                        peers->flags |= PEERS_F_RESYNC_ASSIGN;
+                                        curpeers->flags |= PEERS_F_RESYNC_ASSIGN;
                                 }
 
 
@@ -823,7 +823,7 @@ switchstate:
                                curpeer->statuscode = atoi(trash.str);
 
                                /* Awake main task */
-                               task_wakeup(peers->sync_task, TASK_WOKEN_MSG);
+                               task_wakeup(curpeers->sync_task, TASK_WOKEN_MSG);
 
                                /* If status code is success */
                                if (curpeer->statuscode == PEER_SESS_SC_SUCCESSCODE) {
@@ -846,14 +846,14 @@ switchstate:
                                                 curpeer->flags |= PEER_F_TEACH_PROCESS;
 
                                         }
-                                        else if ((peers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMREMOTE &&
-                                                    !(peers->flags & PEERS_F_RESYNC_ASSIGN)) {
+                                        else if ((curpeers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FROMREMOTE &&
+                                                    !(curpeers->flags & PEERS_F_RESYNC_ASSIGN)) {
                                                 /* If peer is remote and resync from remote is needed,
                                                    and no peer currently assigned */
 
                                                 /* assign peer for a lesson */
                                                 curpeer->flags |= PEER_F_LEARN_ASSIGN;
-                                               peers->flags |= PEERS_F_RESYNC_ASSIGN;
+                                               curpeers->flags |= PEERS_F_RESYNC_ASSIGN;
                                        }
 
                                }
@@ -966,8 +966,8 @@ switchstate:
 
                                                if (curpeer->flags & PEER_F_LEARN_ASSIGN) {
                                                        curpeer->flags &= ~PEER_F_LEARN_ASSIGN;
-                                                       peers->flags &= ~(PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
-                                                       peers->flags |= (PEERS_F_RESYNC_LOCAL|PEERS_F_RESYNC_REMOTE);
+                                                       curpeers->flags &= ~(PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
+                                                       curpeers->flags |= (PEERS_F_RESYNC_LOCAL|PEERS_F_RESYNC_REMOTE);
                                                }
                                                curpeer->confirm++;
                                        }
@@ -975,11 +975,11 @@ switchstate:
 
                                                if (curpeer->flags & PEER_F_LEARN_ASSIGN) {
                                                        curpeer->flags &= ~PEER_F_LEARN_ASSIGN;
-                                                       peers->flags &= ~(PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
+                                                       curpeers->flags &= ~(PEERS_F_RESYNC_ASSIGN|PEERS_F_RESYNC_PROCESS);
 
                                                        curpeer->flags |= PEER_F_LEARN_NOTUP2DATE;
-                                                       peers->resync_timeout = tick_add(now_ms, MS_TO_TICKS(5000));
-                                                       task_wakeup(peers->sync_task, TASK_WOKEN_MSG);
+                                                       curpeers->resync_timeout = tick_add(now_ms, MS_TO_TICKS(5000));
+                                                       task_wakeup(curpeers->sync_task, TASK_WOKEN_MSG);
                                                }
                                                curpeer->confirm++;
                                        }
@@ -1350,8 +1350,8 @@ incomplete:
 
                                /* Need to request a resync */
                                 if ((curpeer->flags & PEER_F_LEARN_ASSIGN) &&
-                                        (peers->flags & PEERS_F_RESYNC_ASSIGN) &&
-                                        !(peers->flags & PEERS_F_RESYNC_PROCESS)) {
+                                        (curpeers->flags & PEERS_F_RESYNC_ASSIGN) &&
+                                        !(curpeers->flags & PEERS_F_RESYNC_PROCESS)) {
                                        unsigned char msg[2];
 
                                         /* Current peer was elected to request a resync */
@@ -1367,7 +1367,7 @@ incomplete:
                                                 appctx->st0 = PEER_SESS_ST_END;
                                                 goto switchstate;
                                         }
-                                        peers->flags |= PEERS_F_RESYNC_PROCESS;
+                                        curpeers->flags |= PEERS_F_RESYNC_PROCESS;
                                 }
 
                                /* Nothing to read, now we start to write */
@@ -1640,7 +1640,7 @@ incomplete:
 
                                         /* Current peer was elected to request a resync */
                                        msg[0] = PEER_MSG_CLASS_CONTROL;
-                                       msg[1] = ((peers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FINISHED) ? PEER_MSG_CTRL_RESYNCFINISHED : PEER_MSG_CTRL_RESYNCPARTIAL;
+                                       msg[1] = ((curpeers->flags & PEERS_RESYNC_STATEMASK) == PEERS_RESYNC_FINISHED) ? PEER_MSG_CTRL_RESYNCFINISHED : PEER_MSG_CTRL_RESYNCPARTIAL;
                                        /* process final lesson message */
                                        repl = bi_putblk(si_ic(si), (char *)msg, sizeof(msg));
                                        if (repl <= 0) {
index f6a32146dc1fb787080c6b105cbb3e10abd66cbf..1481089448519a7b0535d89a4b09e8dcb46ea070 100644 (file)
@@ -1021,7 +1021,7 @@ void soft_stop(void)
                p = p->next;
        }
 
-       prs = peers;
+       prs = cfg_peers;
        while (prs) {
                if (prs->peers_fe)
                        stop_proxy(prs->peers_fe);
@@ -1195,7 +1195,7 @@ void pause_proxies(void)
                p = p->next;
        }
 
-       prs = peers;
+       prs = cfg_peers;
        while (prs) {
                if (prs->peers_fe)
                        err |= !pause_proxy(prs->peers_fe);
@@ -1229,7 +1229,7 @@ void resume_proxies(void)
                p = p->next;
        }
 
-       prs = peers;
+       prs = cfg_peers;
        while (prs) {
                if (prs->peers_fe)
                        err |= !resume_proxy(prs->peers_fe);