mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-12-02 08:11:29 +01:00
BUG/MEDIUM: mworker: signals inconsistencies during startup and reload
Since haproxy 3.1, the master-worker mode changed to let the worker parse the configuration instead of the master. Previously, signals were blocked during configuration parsing and unblocked before entering the polling loop of the master. This way it was impossible to start a reload during the configuration parsing. But with the new model, the polling loop is started in the master before the configuration parsing is finished, and the signals are still unblocked at this step. Meaning that it is possible to start a reload while the configuration is parsing. This patch reintroduce the behavior of blocking the signals during configuration parsing adapted to the new model: - Before the exec() of the reload, signals are blocked. - When entering the polling loop, the SIGCHLD is unblocked because it is required to get a failure during configuration parsing in the worker - Once the configuration is parsed, upon success in _send_status() or upon failure in run_master_in_recovery_mode() every signals are unblocked. This patch must be backported as far as 3.1.
This commit is contained in:
parent
b38405d156
commit
709cde6d08
@ -2652,6 +2652,8 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void
|
||||
if (global.tune.options & GTUNE_USE_SYSTEMD)
|
||||
sd_notifyf(0, "READY=1\nMAINPID=%lu\nSTATUS=Ready.\n", (unsigned long)getpid());
|
||||
|
||||
mworker_unblock_signals();
|
||||
|
||||
/* master and worker have successfully started, now we can set quiet mode
|
||||
* if MODE_DAEMON
|
||||
*/
|
||||
|
||||
@ -2601,6 +2601,7 @@ static void run_master_in_recovery_mode(int argc, char **argv)
|
||||
global.mode |= MODE_QUIET; /* ensure that we won't say anything from now */
|
||||
}
|
||||
|
||||
mworker_unblock_signals();
|
||||
/* enter in master polling loop */
|
||||
mworker_run_master();
|
||||
}
|
||||
|
||||
@ -278,8 +278,35 @@ void mworker_block_signals()
|
||||
ha_sigmask(SIG_SETMASK, &set, NULL);
|
||||
}
|
||||
|
||||
void mworker_unblock_sigchld()
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
signal_register_fct(SIGCHLD, mworker_catch_sigchld, SIGCHLD);
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGCHLD);
|
||||
|
||||
ha_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||
}
|
||||
|
||||
void mworker_unblock_signals()
|
||||
{
|
||||
signal_unregister(SIGTTIN);
|
||||
signal_unregister(SIGTTOU);
|
||||
signal_unregister(SIGUSR1);
|
||||
signal_unregister(SIGHUP);
|
||||
signal_unregister(SIGQUIT);
|
||||
|
||||
signal_register_fct(SIGTERM, mworker_catch_sigterm, SIGTERM);
|
||||
signal_register_fct(SIGUSR1, mworker_catch_sigterm, SIGUSR1);
|
||||
signal_register_fct(SIGTTIN, mworker_broadcast_signal, SIGTTIN);
|
||||
signal_register_fct(SIGTTOU, mworker_broadcast_signal, SIGTTOU);
|
||||
signal_register_fct(SIGINT, mworker_catch_sigterm, SIGINT);
|
||||
signal_register_fct(SIGHUP, mworker_catch_sighup, SIGHUP);
|
||||
signal_register_fct(SIGUSR2, mworker_catch_sighup, SIGUSR2);
|
||||
signal_register_fct(SIGCHLD, mworker_catch_sigchld, SIGCHLD);
|
||||
|
||||
haproxy_unblock_signals();
|
||||
}
|
||||
|
||||
@ -1117,23 +1144,7 @@ static void mworker_loop()
|
||||
/* Busy polling makes no sense in the master :-) */
|
||||
global.tune.options &= ~GTUNE_BUSY_POLLING;
|
||||
|
||||
|
||||
signal_unregister(SIGTTIN);
|
||||
signal_unregister(SIGTTOU);
|
||||
signal_unregister(SIGUSR1);
|
||||
signal_unregister(SIGHUP);
|
||||
signal_unregister(SIGQUIT);
|
||||
|
||||
signal_register_fct(SIGTERM, mworker_catch_sigterm, SIGTERM);
|
||||
signal_register_fct(SIGUSR1, mworker_catch_sigterm, SIGUSR1);
|
||||
signal_register_fct(SIGTTIN, mworker_broadcast_signal, SIGTTIN);
|
||||
signal_register_fct(SIGTTOU, mworker_broadcast_signal, SIGTTOU);
|
||||
signal_register_fct(SIGINT, mworker_catch_sigterm, SIGINT);
|
||||
signal_register_fct(SIGHUP, mworker_catch_sighup, SIGHUP);
|
||||
signal_register_fct(SIGUSR2, mworker_catch_sighup, SIGUSR2);
|
||||
signal_register_fct(SIGCHLD, mworker_catch_sigchld, SIGCHLD);
|
||||
|
||||
mworker_unblock_signals();
|
||||
mworker_unblock_sigchld();
|
||||
mworker_cleantasks();
|
||||
|
||||
mworker_catch_sigchld(NULL); /* ensure we clean the children in case
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user