BUG/MEDIUM: mworker: do not register an exit handler if exit is expected
The master-worker code registers an exit handler to deal with configuration
issues during reload, leading to a restart of the master process in wait
mode. But it shouldn't do that when it's expected that the program stops
during config parsing or condition checks, as the reload operation is
unexpectedly called and results in abnormal behavior and even crashes:
$ HAPROXY_MWORKER_REEXEC=1 ./haproxy -W -c -f /dev/null
Configuration file is valid
[NOTICE] (18418) : haproxy version is 2.5-dev2-ee2420-6
[NOTICE] (18418) : path to executable is ./haproxy
[WARNING] (18418) : config : Reexecuting Master process in waitpid mode
Segmentation fault
$ HAPROXY_MWORKER_REEXEC=1 ./haproxy -W -cc 1
[NOTICE] (18412) : haproxy version is 2.5-dev2-ee2420-6
[NOTICE] (18412) : path to executable is ./haproxy
[WARNING] (18412) : config : Reexecuting Master process in waitpid mode
[WARNING] (18412) : config : Reexecuting Master process
Note that the presence of this variable happens by accident when haproxy
is called from within its own programs (see issue #1324), but this should
be the object of a separate fix.
This patch fixes this by preventing the atexit registration in such
situations. This should be backported as far as 1.8. MODE_CHECK_CONDITION
has to be dropped for versions prior to 2.5.
(cherry picked from commit 26146194d3c2945ad3d692fbcddaf8d5525117a4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 7a534ebcef5531152691c4efbd9e434ba196e924)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e63b9c9857ac626d98b9fa3f145a02199a9f5a1b)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit f1b493f54f01a7cfd274090cfbd5b4840847be5a)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/haproxy.c b/src/haproxy.c
index 9bf5b3a..87f6843 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1816,7 +1816,8 @@
global.mode &= ~MODE_MWORKER;
}
- if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
+ if ((global.mode & (MODE_MWORKER | MODE_CHECK)) == MODE_MWORKER &&
+ (getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
atexit_flag = 1;
atexit(reexec_on_failure);
}