mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-19 21:45:33 +00:00
MEDIUM: mworker: wait mode use standard init code path
The mworker waitpid mode (which is used when a reload failed to apply the new configuration) was still using a specific initialisation path. That's a problem since we use a polling loop in the master now, the master proxy is not initialized and the master CLI is not activated. This patch removes the initialisation code of the wait mode and introduce the MODE_MWORKER_WAIT in order to use the same init path as the MODE_MWORKER with some exceptions. It allows to use the master proxy and the master CLI during the waitpid mode.
This commit is contained in:
parent
7e346f3694
commit
944e619b64
@ -47,6 +47,7 @@
|
||||
#define MODE_STARTING 0x20
|
||||
#define MODE_FOREGROUND 0x40
|
||||
#define MODE_MWORKER 0x80 /* Master Worker */
|
||||
#define MODE_MWORKER_WAIT 0x100 /* Master Worker wait mode */
|
||||
|
||||
/* list of last checks to perform, depending on config options */
|
||||
#define LSTCHK_CAP_BIND 0x00000001 /* check that we can bind to any port */
|
||||
|
184
src/haproxy.c
184
src/haproxy.c
@ -753,14 +753,6 @@ static void mworker_reload()
|
||||
next_argv[next_argc++] = NULL;
|
||||
}
|
||||
|
||||
if (getenv("HAPROXY_MWORKER_WAIT_ONLY") == NULL) {
|
||||
struct per_thread_deinit_fct *ptdf;
|
||||
|
||||
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
|
||||
ptdf->fct();
|
||||
deinit_pollers(); /* we don't want to leak the poller fd */
|
||||
}
|
||||
|
||||
ha_warning("Reexecuting Master process\n");
|
||||
execvp(next_argv[0], next_argv);
|
||||
|
||||
@ -895,40 +887,6 @@ static void mworker_loop()
|
||||
run_thread_poll_loop((int []){0});
|
||||
}
|
||||
|
||||
/*
|
||||
* This function initialize haproxy for the master wait mode, it won't fork any
|
||||
* new process and won't parse the configuration
|
||||
*/
|
||||
static int mworker_wait_mode()
|
||||
{
|
||||
|
||||
global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
|
||||
|
||||
if (!(global.tune.options & GTUNE_USE_KQUEUE))
|
||||
disable_poller("kqueue");
|
||||
|
||||
if (!(global.tune.options & GTUNE_USE_EPOLL))
|
||||
disable_poller("epoll");
|
||||
|
||||
if (!(global.tune.options & GTUNE_USE_POLL))
|
||||
disable_poller("poll");
|
||||
|
||||
if (!(global.tune.options & GTUNE_USE_SELECT))
|
||||
disable_poller("select");
|
||||
|
||||
if (global.tune.maxpollevents <= 0)
|
||||
global.tune.maxpollevents = MAX_POLL_EVENTS;
|
||||
|
||||
init_pollers();
|
||||
|
||||
|
||||
mworker_loop();
|
||||
|
||||
/* should never be there */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reexec the process in failure mode, instead of exiting
|
||||
*/
|
||||
@ -1681,11 +1639,10 @@ static void init(int argc, char **argv)
|
||||
global.mode |= (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)) {
|
||||
|
||||
if (getenv("HAPROXY_MWORKER_WAIT_ONLY")) {
|
||||
unsetenv("HAPROXY_MWORKER_WAIT_ONLY");
|
||||
mworker_wait_mode();
|
||||
global.mode |= MODE_MWORKER_WAIT;
|
||||
global.mode &= ~MODE_MWORKER;
|
||||
}
|
||||
|
||||
if ((global.mode & MODE_MWORKER) && (getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
|
||||
@ -1698,44 +1655,47 @@ static void init(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* handle cfgfiles that are actually directories */
|
||||
cfgfiles_expand_directories();
|
||||
|
||||
if (LIST_ISEMPTY(&cfg_cfgfiles))
|
||||
usage(progname);
|
||||
|
||||
global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
|
||||
|
||||
init_default_instance();
|
||||
|
||||
list_for_each_entry(wl, &cfg_cfgfiles, list) {
|
||||
int ret;
|
||||
/* in wait mode, we don't try to read the configuration files */
|
||||
if (!(global.mode & MODE_MWORKER_WAIT)) {
|
||||
|
||||
ret = readcfgfile(wl->s);
|
||||
if (ret == -1) {
|
||||
ha_alert("Could not open configuration file %s : %s\n",
|
||||
wl->s, strerror(errno));
|
||||
/* handle cfgfiles that are actually directories */
|
||||
cfgfiles_expand_directories();
|
||||
|
||||
if (LIST_ISEMPTY(&cfg_cfgfiles))
|
||||
usage(progname);
|
||||
|
||||
|
||||
list_for_each_entry(wl, &cfg_cfgfiles, list) {
|
||||
int ret;
|
||||
|
||||
ret = readcfgfile(wl->s);
|
||||
if (ret == -1) {
|
||||
ha_alert("Could not open configuration file %s : %s\n",
|
||||
wl->s, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (ret & (ERR_ABORT|ERR_FATAL))
|
||||
ha_alert("Error(s) found in configuration file : %s\n", wl->s);
|
||||
err_code |= ret;
|
||||
if (err_code & ERR_ABORT)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* do not try to resolve arguments nor to spot inconsistencies when
|
||||
* the configuration contains fatal errors caused by files not found
|
||||
* or failed memory allocations.
|
||||
*/
|
||||
if (err_code & (ERR_ABORT|ERR_FATAL)) {
|
||||
ha_alert("Fatal errors found in configuration.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ret & (ERR_ABORT|ERR_FATAL))
|
||||
ha_alert("Error(s) found in configuration file : %s\n", wl->s);
|
||||
err_code |= ret;
|
||||
if (err_code & ERR_ABORT)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* do not try to resolve arguments nor to spot inconsistencies when
|
||||
* the configuration contains fatal errors caused by files not found
|
||||
* or failed memory allocations.
|
||||
*/
|
||||
if (err_code & (ERR_ABORT|ERR_FATAL)) {
|
||||
ha_alert("Fatal errors found in configuration.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (global.mode & MODE_MWORKER) {
|
||||
int proc;
|
||||
struct wordlist *it, *c;
|
||||
struct mworker_proc *tmproc;
|
||||
|
||||
if (getenv("HAPROXY_MWORKER_REEXEC") == NULL) {
|
||||
@ -1780,6 +1740,10 @@ static void init(int argc, char **argv)
|
||||
|
||||
LIST_ADDQ(&proc_list, &tmproc->list);
|
||||
}
|
||||
}
|
||||
if (global.mode & (MODE_MWORKER|MODE_MWORKER_WAIT)) {
|
||||
struct wordlist *it, *c;
|
||||
|
||||
mworker_env_to_proc_list(); /* get the info of the children in the env */
|
||||
|
||||
|
||||
@ -2847,7 +2811,7 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listeners == 0) {
|
||||
if (!(global.mode & MODE_MWORKER_WAIT) && listeners == 0) {
|
||||
ha_alert("[%s.main()] No enabled listener found (check for 'bind' directives) ! Exiting.\n", argv[0]);
|
||||
/* Note: we don't have to send anything to the old pids because we
|
||||
* never stopped them. */
|
||||
@ -2941,7 +2905,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (nb_oldpids)
|
||||
if (nb_oldpids && !(global.mode & MODE_MWORKER_WAIT))
|
||||
nb_oldpids = tell_old_pids(oldpids_sig);
|
||||
|
||||
if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL)) {
|
||||
@ -2983,14 +2947,13 @@ int main(int argc, char **argv)
|
||||
argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, global.maxsock);
|
||||
}
|
||||
|
||||
if (global.mode & (MODE_DAEMON | MODE_MWORKER)) {
|
||||
if (global.mode & (MODE_DAEMON | MODE_MWORKER | MODE_MWORKER_WAIT)) {
|
||||
struct proxy *px;
|
||||
struct peers *curpeers;
|
||||
int ret = 0;
|
||||
int proc;
|
||||
int devnullfd = -1;
|
||||
|
||||
children = calloc(global.nbproc, sizeof(int));
|
||||
/*
|
||||
* if daemon + mworker: must fork here to let a master
|
||||
* process live in background before forking children
|
||||
@ -3020,38 +2983,45 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* the father launches the required number of processes */
|
||||
for (proc = 0; proc < global.nbproc; proc++) {
|
||||
ret = fork();
|
||||
if (ret < 0) {
|
||||
ha_alert("[%s.main()] Cannot fork.\n", argv[0]);
|
||||
protocol_unbind_all();
|
||||
exit(1); /* there has been an error */
|
||||
}
|
||||
else if (ret == 0) /* child breaks here */
|
||||
break;
|
||||
children[proc] = ret;
|
||||
if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) {
|
||||
char pidstr[100];
|
||||
snprintf(pidstr, sizeof(pidstr), "%d\n", ret);
|
||||
shut_your_big_mouth_gcc(write(pidfd, pidstr, strlen(pidstr)));
|
||||
}
|
||||
if (global.mode & MODE_MWORKER) {
|
||||
struct mworker_proc *child;
|
||||
if (!(global.mode & MODE_MWORKER_WAIT)) {
|
||||
children = calloc(global.nbproc, sizeof(int));
|
||||
for (proc = 0; proc < global.nbproc; proc++) {
|
||||
ret = fork();
|
||||
if (ret < 0) {
|
||||
ha_alert("[%s.main()] Cannot fork.\n", argv[0]);
|
||||
protocol_unbind_all();
|
||||
exit(1); /* there has been an error */
|
||||
}
|
||||
else if (ret == 0) /* child breaks here */
|
||||
break;
|
||||
children[proc] = ret;
|
||||
if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) {
|
||||
char pidstr[100];
|
||||
snprintf(pidstr, sizeof(pidstr), "%d\n", ret);
|
||||
shut_your_big_mouth_gcc(write(pidfd, pidstr, strlen(pidstr)));
|
||||
}
|
||||
if (global.mode & MODE_MWORKER) {
|
||||
struct mworker_proc *child;
|
||||
|
||||
qfprintf(stdout, "New worker #%d (%d) forked\n", relative_pid, ret);
|
||||
/* find the right mworker_proc */
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
if (child->relative_pid == relative_pid &&
|
||||
child->reloads == 0) {
|
||||
child->timestamp = now.tv_sec;
|
||||
child->pid = ret;
|
||||
break;
|
||||
qfprintf(stdout, "New worker #%d (%d) forked\n", relative_pid, ret);
|
||||
/* find the right mworker_proc */
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
if (child->relative_pid == relative_pid &&
|
||||
child->reloads == 0) {
|
||||
child->timestamp = now.tv_sec;
|
||||
child->pid = ret;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relative_pid++; /* each child will get a different one */
|
||||
pid_bit <<= 1;
|
||||
relative_pid++; /* each child will get a different one */
|
||||
pid_bit <<= 1;
|
||||
}
|
||||
} else {
|
||||
/* wait mode */
|
||||
global.nbproc = 1;
|
||||
proc = 1;
|
||||
}
|
||||
|
||||
#ifdef USE_CPU_AFFINITY
|
||||
@ -3085,7 +3055,7 @@ int main(int argc, char **argv)
|
||||
free(global.pidfile); global.pidfile = NULL;
|
||||
|
||||
if (proc == global.nbproc) {
|
||||
if (global.mode & MODE_MWORKER) {
|
||||
if (global.mode & (MODE_MWORKER|MODE_MWORKER_WAIT)) {
|
||||
|
||||
if ((!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) &&
|
||||
(global.mode & MODE_DAEMON)) {
|
||||
|
Loading…
Reference in New Issue
Block a user