]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: peers: re-work connection to new process during reload.
authorEmeric Brun <ebrun@haproxy.com>
Thu, 22 Apr 2021 16:20:37 +0000 (18:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 23 Apr 2021 16:03:06 +0000 (18:03 +0200)
The peers task handling the "stopping" could wake up multiple
times in stopping state with WOKEN_SIGNAL: the connection to the
local peer initiated on the first processing was immediatly
shutdown by the next processing of the task and the old process
exits considering it is unable to connect. It results on
empty stick-tables after a reload.

This patch checks the flag 'PEERS_F_DONOTSTOP' to know if the
signal is considered and if remote peers connections shutdown
is already done or if a connection to the local peer must be
established.

This patch should be backported on all supported branches (v >= 1.6)

src/peers.c

index d8f0b747591bc10322a3bcf38e3519f43bd1c803..dd1d2596e46d2d4e2cf90eab50d4d46e2d6eee2b 100644 (file)
@@ -3041,17 +3041,20 @@ struct task *process_peer_sync(struct task * task, void *context, unsigned int s
                                ps = peers->local;
                                for (st = ps->tables; st ; st = st->next)
                                        st->table->syncing++;
-                       }
 
-                       /* disconnect all connected peers */
-                       for (ps = peers->remote; ps; ps = ps->next) {
-                               /* we're killing a connection, we must apply a random delay before
-                                * retrying otherwise the other end will do the same and we can loop
-                                * for a while.
+                               /* disconnect all connected peers to process a local sync
+                                * this must be done only the first time we are switching
+                                * in stopping state
                                 */
-                               ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + ha_random() % 2000));
-                               if (ps->appctx) {
-                                       peer_session_forceshutdown(ps);
+                               for (ps = peers->remote; ps; ps = ps->next) {
+                                       /* we're killing a connection, we must apply a random delay before
+                                        * retrying otherwise the other end will do the same and we can loop
+                                        * for a while.
+                                        */
+                                       ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + ha_random() % 2000));
+                                       if (ps->appctx) {
+                                               peer_session_forceshutdown(ps);
+                                       }
                                }
                        }
                }
@@ -3077,8 +3080,10 @@ struct task *process_peer_sync(struct task * task, void *context, unsigned int s
                                 * or previous tcp connect succeeded but init state incomplete
                                 * or during previous connect, peer replies a try again statuscode */
 
-                               /* connect to the peer */
-                               peer_session_create(peers, ps);
+                               /* connect to the local peer if we must push a local sync */
+                               if (peers->flags & PEERS_F_DONOTSTOP) {
+                                       peer_session_create(peers, ps);
+                               }
                        }
                        else {
                                /* Other error cases */