MEDIUM: mworker: wait mode on reload failure
In Master Worker mode, when the reloading of the configuration fail, the process is exiting leaving the children without their father. To handle this, we register an exit function with atexit(3), which is reexecuting the binary in a special mode. This particular mode of HAProxy don't reload the configuration, it only loops on wait().
This commit is contained in:
parent
73b85e75b3
commit
cb11fd2c7a
@ -181,6 +181,8 @@ struct chunk trash = { };
|
||||
*/
|
||||
char *swap_buffer = NULL;
|
||||
|
||||
int atexit_flag = 0;
|
||||
|
||||
int nb_oldpids = 0;
|
||||
const int zero = 0;
|
||||
const int one = 1;
|
||||
@ -592,6 +594,7 @@ static void mworker_wait()
|
||||
|
||||
if (exitpid == -1 && errno == ECHILD) {
|
||||
Warning("All workers are left. Leaving... (%d)\n", status);
|
||||
atexit_flag = 0;
|
||||
exit(status); /* parent must leave using the latest status code known */
|
||||
}
|
||||
|
||||
@ -619,6 +622,22 @@ static void mworker_wait()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reexec the process in failure mode, instead of exiting
|
||||
*/
|
||||
void reexec_on_failure()
|
||||
{
|
||||
if (!atexit_flag)
|
||||
return;
|
||||
|
||||
setenv("HAPROXY_MWORKER_WAIT_ONLY", "1", 1);
|
||||
|
||||
Warning("Reexecuting Master process in waitpid mode\n");
|
||||
mworker_reload();
|
||||
|
||||
Warning("Failed to reexecute the master processs\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upon SIGUSR1, let's have a soft stop. Note that soft_stop() broadcasts
|
||||
@ -1270,6 +1289,18 @@ static void init(int argc, char **argv)
|
||||
(arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
|
||||
| MODE_QUIET | MODE_CHECK | MODE_DEBUG));
|
||||
|
||||
/* Master workers wait mode */
|
||||
if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_WAIT_ONLY") != NULL)) {
|
||||
|
||||
unsetenv("HAPROXY_MWORKER_WAIT_ONLY");
|
||||
mworker_wait();
|
||||
}
|
||||
|
||||
if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
|
||||
atexit_flag = 1;
|
||||
atexit(reexec_on_failure);
|
||||
}
|
||||
|
||||
if (change_dir && chdir(change_dir) < 0) {
|
||||
Alert("Could not change to directory %s : %s\n", change_dir, strerror(errno));
|
||||
exit(1);
|
||||
@ -2422,9 +2453,13 @@ int main(int argc, char **argv)
|
||||
#ifndef OPENSSL_NO_DH
|
||||
ssl_free_dh();
|
||||
#endif
|
||||
exit(0); /* parent must leave */
|
||||
/* should never get there */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* child must never use the atexit function */
|
||||
atexit_flag = 0;
|
||||
|
||||
/* Must chroot and setgid/setuid in the children */
|
||||
/* chroot if needed */
|
||||
if (global.chroot != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user