|
commit b143711afe833f9824a7372b88ef9435ff240e9a
|
|
Author: Willy Tarreau <w@1wt.eu>
|
|
Date: Tue Sep 3 18:55:02 2019 +0200
|
|
|
|
BUG/MEDIUM: check/threads: make external checks run exclusively on thread 1
|
|
|
|
See GH issues #141 for all the context. In short, registered signal
|
|
handlers are not inherited by other threads during startup, which is
|
|
normally not a problem, except that we need that the same thread as
|
|
the one doing the fork() cleans up the old process using waitpid()
|
|
once its death is reported via SIGCHLD, as happens in external checks.
|
|
|
|
The only simple solution to this at the moment is to make sure that
|
|
external checks are exclusively run on the first thread, the one
|
|
which registered the signal handlers on startup. It will be far more
|
|
than enough anyway given that external checks must not require to be
|
|
load balanced on multiple threads! A more complex solution could be
|
|
designed over the long term to let each thread deal with all signals
|
|
but it sounds overkill.
|
|
|
|
This must be backported as far as 1.8.
|
|
|
|
(cherry picked from commit 6dd4ac890b5810b0f0fe81725fda05ad3d052849)
|
|
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
|
|
|
diff --git a/src/checks.c b/src/checks.c
|
|
index 7b55abda..b088da2e 100644
|
|
--- a/src/checks.c
|
|
+++ b/src/checks.c
|
|
@@ -2175,7 +2175,7 @@ static struct task *process_chk_proc(struct task *t, void *context, unsigned sho
|
|
/* a success was detected */
|
|
check_notify_success(check);
|
|
}
|
|
- task_set_affinity(t, MAX_THREADS_MASK);
|
|
+ task_set_affinity(t, 1);
|
|
check->state &= ~CHK_ST_INPROGRESS;
|
|
|
|
pid_list_del(check->curpid);
|
|
@@ -2423,8 +2423,13 @@ static int start_check_task(struct check *check, int mininter,
|
|
int nbcheck, int srvpos)
|
|
{
|
|
struct task *t;
|
|
+ unsigned long thread_mask = MAX_THREADS_MASK;
|
|
+
|
|
+ if (check->type == PR_O2_EXT_CHK)
|
|
+ thread_mask = 1;
|
|
+
|
|
/* task for the check */
|
|
- if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
|
|
+ if ((t = task_new(thread_mask)) == NULL) {
|
|
ha_alert("Starting [%s:%s] check: out of memory.\n",
|
|
check->server->proxy->id, check->server->id);
|
|
return 0;
|