BUG/MEDIUM: mworker: also close peers sockets in the master

There's a nasty case related to signaling all processes via SIGUSR1.
Since the master process still holds the peers sockets, the old process
trying to connect to the new one to teach it its tables has a risk to
connect to the master instead, which will not do anything, causing the
old process to hang instead of quitting.

This patch ensures we correctly close the peers in the master process
on startup, just like it is done for proxies. Ultimately we would rather
have a complete list of listeners to avoid such issues. But that's a bit
trickier as it would require using unbind_all() and avoiding side effects
the master could cause to other processes (like unlinking unix sockets).

To be backported to 1.8.
This commit is contained in:
Willy Tarreau 2017-12-05 11:14:12 +01:00
parent c61c0b371b
commit 473cf5d0cd
1 changed files with 16 additions and 0 deletions

View File

@ -555,8 +555,24 @@ static void mworker_cleanlisteners()
{ {
struct listener *l, *l_next; struct listener *l, *l_next;
struct proxy *curproxy; struct proxy *curproxy;
struct peers *curpeers;
for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) { for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
/* we might have to unbind some peers sections from some processes */
for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
if (!curpeers->peers_fe)
continue;
stop_proxy(curpeers->peers_fe);
/* disable this peer section so that it kills itself */
signal_unregister_handler(curpeers->sighandler);
task_delete(curpeers->sync_task);
task_free(curpeers->sync_task);
curpeers->sync_task = NULL;
task_free(curpeers->peers_fe->task);
curpeers->peers_fe->task = NULL;
curpeers->peers_fe = NULL;
}
list_for_each_entry_safe(l, l_next, &curproxy->conf.listeners, by_fe) { list_for_each_entry_safe(l, l_next, &curproxy->conf.listeners, by_fe) {
/* does not close if the FD is inherited with fd@ /* does not close if the FD is inherited with fd@