mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 12:41:00 +02:00
BUG/MINOR: proxy: always lock stop_proxy()
There is one unprotected call to stop_proxy() from the manage_proxy() task, so there is a single caller by definition, but there is also another such call from the CLI's "shutdown frontend" parser. This one does it under the proxy's lock but the first one doesn't use it. Thus it is theorically possible to corrupt the list of listeners in a proxy by issuing "shutdown frontend" and SIGUSR1 exactly at the same time. While it sounds particularly contrived or stupid, it could possibly happen with automated tools that would send actions via various channels. This could cause the process to loop forever or to crash and thus stop faster than expected. This might be backported as far as 1.8.
This commit is contained in:
parent
daacf36645
commit
3de3cd4d97
10
src/proxy.c
10
src/proxy.c
@ -1243,13 +1243,16 @@ void zombify_proxy(struct proxy *p)
|
||||
* to be called when going down in order to release the ports so that another
|
||||
* process may bind to them. It must also be called on disabled proxies at the
|
||||
* end of start-up. If all listeners are closed, the proxy is set to the
|
||||
* PR_STSTOPPED state.
|
||||
* PR_STSTOPPED state. The function takes the proxy's lock so it's safe to
|
||||
* call from multiple places.
|
||||
*/
|
||||
void stop_proxy(struct proxy *p)
|
||||
{
|
||||
struct listener *l;
|
||||
int nostop = 0;
|
||||
|
||||
HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
|
||||
|
||||
list_for_each_entry(l, &p->conf.listeners, by_fe) {
|
||||
if (l->options & LI_O_NOSTOP) {
|
||||
HA_ATOMIC_ADD(&unstoppable_jobs, 1);
|
||||
@ -1263,6 +1266,8 @@ void stop_proxy(struct proxy *p)
|
||||
}
|
||||
if (!nostop)
|
||||
p->state = PR_STSTOPPED;
|
||||
|
||||
HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
|
||||
}
|
||||
|
||||
/* This function resumes listening on the specified proxy. It scans all of its
|
||||
@ -2070,10 +2075,7 @@ static int cli_parse_shutdown_frontend(char **args, char *payload, struct appctx
|
||||
send_log(px, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
|
||||
px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
|
||||
|
||||
HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
|
||||
stop_proxy(px);
|
||||
HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user