]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: proxy: do not wake stopped proxies' tasks during soft_stop()
authorWilly Tarreau <w@1wt.eu>
Mon, 28 Sep 2015 14:35:04 +0000 (16:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 28 Sep 2015 14:35:04 +0000 (16:35 +0200)
When performing a soft stop, we used to wake up every proxy's task and
each of their table's task. The problem is that since we're able to stop
proxies and peers not bound to a specific process, we may end up calling
random junk by doing so of the proxy we're waking up is already stopped.
This causes a segfault to appear during soft reloads for old processes
not bound to a peers section if such a section exists in other processes.

Let's only consider proxies that are not stopped when doing this.

This fix must be backported to 1.5 which also has the same issue.

src/proxy.c

index 1f2fc56156974e729a9034ca3f4ed9c266670ef8..194d4bdf600b234b08df53b1cade447addf6a5c0 100644 (file)
@@ -925,13 +925,16 @@ void soft_stop(void)
                        Warning("Stopping %s %s in %d ms.\n", proxy_cap_str(p->cap), p->id, p->grace);
                        send_log(p, LOG_WARNING, "Stopping %s %s in %d ms.\n", proxy_cap_str(p->cap), p->id, p->grace);
                        p->stop_time = tick_add(now_ms, p->grace);
-               }
-               if (p->table.size && p->table.sync_task)
-                        task_wakeup(p->table.sync_task, TASK_WOKEN_MSG);
 
-               /* wake every proxy task up so that they can handle the stopping */
-               if (p->task)
-                       task_wakeup(p->task, TASK_WOKEN_MSG);
+                       /* Note: do not wake up stopped proxies' task nor their tables'
+                        * tasks as these ones might point to already released entries.
+                        */
+                       if (p->table.size && p->table.sync_task)
+                               task_wakeup(p->table.sync_task, TASK_WOKEN_MSG);
+
+                       if (p->task)
+                               task_wakeup(p->task, TASK_WOKEN_MSG);
+               }
                p = p->next;
        }