mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MEDIUM: mworker: workers exit when the master leaves
This patch ensure that the children will exit when the master quits, even if the master didn't send any signal. The master and the workers are connected through a pipe, when the pipe closes the children leave.
This commit is contained in:
parent
69f9b3bfa4
commit
e20b6a62f8
@ -203,6 +203,8 @@ int *children = NULL; /* store PIDs of children in master workers mode */
|
||||
static volatile sig_atomic_t caught_signal = 0;
|
||||
static char **next_argv = NULL;
|
||||
|
||||
int mworker_pipe[2];
|
||||
|
||||
/* list of the temporarily limited listeners because of lack of resource */
|
||||
struct list global_listener_queue = LIST_HEAD_INIT(global_listener_queue);
|
||||
struct task *global_listener_queue_task;
|
||||
@ -2225,6 +2227,37 @@ static struct task *manage_global_listener_queue(struct task *t)
|
||||
return t;
|
||||
}
|
||||
|
||||
void mworker_pipe_handler(int fd)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (read(fd, &c, 1) == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == EAGAIN) {
|
||||
fd_cant_recv(fd);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
deinit();
|
||||
exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
void mworker_pipe_register(int pipefd[2])
|
||||
{
|
||||
close(mworker_pipe[1]); /* close the write end of the master pipe in the children */
|
||||
|
||||
fcntl(mworker_pipe[0], F_SETFL, O_NONBLOCK);
|
||||
fdtab[mworker_pipe[0]].owner = mworker_pipe;
|
||||
fdtab[mworker_pipe[0]].iocb = mworker_pipe_handler;
|
||||
fd_insert(mworker_pipe[0]);
|
||||
fd_want_recv(mworker_pipe[0]);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int err, retry;
|
||||
@ -2475,6 +2508,30 @@ int main(int argc, char **argv)
|
||||
if (ret > 0)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (global.mode & MODE_MWORKER) {
|
||||
if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL)) {
|
||||
char *msg = NULL;
|
||||
/* master pipe to ensure the master is still alive */
|
||||
ret = pipe(mworker_pipe);
|
||||
if (ret < 0) {
|
||||
Warning("[%s.main()] Cannot create master pipe.\n", argv[0]);
|
||||
} else {
|
||||
memprintf(&msg, "%d", mworker_pipe[0]);
|
||||
setenv("HAPROXY_MWORKER_PIPE_RD", msg, 1);
|
||||
memprintf(&msg, "%d", mworker_pipe[1]);
|
||||
setenv("HAPROXY_MWORKER_PIPE_WR", msg, 1);
|
||||
free(msg);
|
||||
}
|
||||
} else {
|
||||
mworker_pipe[0] = atol(getenv("HAPROXY_MWORKER_PIPE_RD"));
|
||||
mworker_pipe[1] = atol(getenv("HAPROXY_MWORKER_PIPE_WR"));
|
||||
if (mworker_pipe[0] <= 0 || mworker_pipe[1] <= 0) {
|
||||
Warning("[%s.main()] Cannot get master pipe FDs.\n", argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the father launches the required number of processes */
|
||||
for (proc = 0; proc < global.nbproc; proc++) {
|
||||
ret = fork();
|
||||
@ -2633,6 +2690,9 @@ int main(int argc, char **argv)
|
||||
if (!dns_init_resolvers(1))
|
||||
exit(1);
|
||||
|
||||
if (global.mode & MODE_MWORKER)
|
||||
mworker_pipe_register(mworker_pipe);
|
||||
|
||||
protocol_enable_all();
|
||||
/*
|
||||
* That's it : the central polling loop. Run until we stop.
|
||||
|
Loading…
x
Reference in New Issue
Block a user