MINOR: mworker: don't use children variable anymore

The children variable is still used in haproxy, it is not required
anymore since we have the information about the current workers in the
mworker_proc linked list.

The oldpids array is also replaced by this linked list when we
generated the arguments for the master reexec.
This commit is contained in:
William Lallemand 2019-04-01 11:29:59 +02:00 committed by Willy Tarreau
parent f3a86831ae
commit 3f12887ffa
3 changed files with 52 additions and 36 deletions

View File

@ -31,6 +31,7 @@ void mworker_pipe_register();
void mworker_cleanlisteners(); void mworker_cleanlisteners();
extern int *children; /* store PIDs of children in master workers mode */ int mworker_child_nb();
#endif /* PROTO_MWORKER_H_ */ #endif /* PROTO_MWORKER_H_ */

View File

@ -557,7 +557,6 @@ static void get_cur_unixsocket()
void mworker_reload() void mworker_reload()
{ {
int next_argc = 0; int next_argc = 0;
int j;
char *msg = NULL; char *msg = NULL;
struct rlimit limit; struct rlimit limit;
struct per_thread_deinit_fct *ptdf; struct per_thread_deinit_fct *ptdf;
@ -598,29 +597,27 @@ void mworker_reload()
next_argc++; next_argc++;
/* 1 for haproxy -sf, 2 for -x /socket */ /* 1 for haproxy -sf, 2 for -x /socket */
next_argv = realloc(next_argv, (next_argc + 1 + 2 + global.nbproc + nb_oldpids + 1) * sizeof(char *)); next_argv = realloc(next_argv, (next_argc + 1 + 2 + mworker_child_nb() + nb_oldpids + 1) * sizeof(char *));
if (next_argv == NULL) if (next_argv == NULL)
goto alloc_error; goto alloc_error;
/* add -sf <PID>* to argv */ /* add -sf <PID>* to argv */
if (children || nb_oldpids > 0) if (mworker_child_nb() > 0) {
struct mworker_proc *child;
next_argv[next_argc++] = "-sf"; next_argv[next_argc++] = "-sf";
if (children) {
for (j = 0; j < global.nbproc; next_argc++,j++) { list_for_each_entry(child, &proc_list, list) {
next_argv[next_argc] = memprintf(&msg, "%d", children[j]); if (child->type != 'w' && child->type != 'e')
continue;
next_argv[next_argc] = memprintf(&msg, "%d", child->pid);
if (next_argv[next_argc] == NULL) if (next_argv[next_argc] == NULL)
goto alloc_error; goto alloc_error;
msg = NULL; msg = NULL;
next_argc++;
} }
} }
/* copy old process PIDs */
for (j = 0; j < nb_oldpids; next_argc++,j++) {
next_argv[next_argc] = memprintf(&msg, "%d", oldpids[j]);
if (next_argv[next_argc] == NULL)
goto alloc_error;
msg = NULL;
}
next_argv[next_argc] = NULL; next_argv[next_argc] = NULL;
/* add the -x option with the stat socket */ /* add the -x option with the stat socket */
@ -2844,7 +2841,6 @@ int main(int argc, char **argv)
/* the father launches the required number of processes */ /* the father launches the required number of processes */
if (!(global.mode & MODE_MWORKER_WAIT)) { if (!(global.mode & MODE_MWORKER_WAIT)) {
children = calloc(global.nbproc, sizeof(int));
for (proc = 0; proc < global.nbproc; proc++) { for (proc = 0; proc < global.nbproc; proc++) {
ret = fork(); ret = fork();
if (ret < 0) { if (ret < 0) {
@ -2854,7 +2850,6 @@ int main(int argc, char **argv)
} }
else if (ret == 0) /* child breaks here */ else if (ret == 0) /* child breaks here */
break; break;
children[proc] = ret;
if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) { if (pidfd >= 0 && !(global.mode & MODE_MWORKER)) {
char pidstr[100]; char pidstr[100];
snprintf(pidstr, sizeof(pidstr), "%d\n", ret); snprintf(pidstr, sizeof(pidstr), "%d\n", ret);

View File

@ -36,8 +36,6 @@
static int exitcode = -1; static int exitcode = -1;
int *children = NULL; /* store PIDs of children in master workers mode */
/* ----- children processes handling ----- */ /* ----- children processes handling ----- */
/* /*
@ -46,29 +44,46 @@ int *children = NULL; /* store PIDs of children in master workers mode */
static void mworker_kill(int sig) static void mworker_kill(int sig)
{ {
int i; struct mworker_proc *child;
/* TODO: merge mworker_kill and tell_old_pids for mworker mode */ list_for_each_entry(child, &proc_list, list) {
tell_old_pids(sig); /* careful there, we must be sure that the pid > 0, we don't want to emit a kill -1 */
if (children) { if ((child->type == 'w' || child->type == 'e') && (child->reloads == 0) && (child->pid > 0))
for (i = 0; i < global.nbproc; i++) kill(child->pid, sig);
kill(children[i], sig);
} }
} }
/* return 1 if a pid is a current child otherwise 0 */ /* return 1 if a pid is a current child otherwise 0 */
int current_child(int pid) int mworker_current_child(int pid)
{ {
int i; struct mworker_proc *child;
for (i = 0; i < global.nbproc; i++) { list_for_each_entry(child, &proc_list, list) {
if (children[i] == pid) if ((child->type == 'w' || child->type == 'e') && (child->reloads == 0) && (child->pid == pid))
return 1; return 1;
} }
return 0; return 0;
} }
/*
* Return the number of new and old children (including workers and external
* processes)
*/
int mworker_child_nb()
{
struct mworker_proc *child;
int ret = 0;
list_for_each_entry(child, &proc_list, list) {
if ((child->type == 'w' || child->type == 'e'))
ret++;
}
return ret;
}
/* /*
* serialize the proc list and put it in the environment * serialize the proc list and put it in the environment
*/ */
@ -204,6 +219,7 @@ restart_wait:
else else
status = 255; status = 255;
/* delete the child from the process list */
list_for_each_entry_safe(child, it, &proc_list, list) { list_for_each_entry_safe(child, it, &proc_list, list) {
if (child->pid != exitpid) if (child->pid != exitpid)
continue; continue;
@ -214,12 +230,15 @@ restart_wait:
break; break;
} }
if (!children || !childfound) { if (!childfound) {
/* We didn't find the PID in the list, that shouldn't happen but we can emit a warning */
ha_warning("Worker %d exited with code %d (%s)\n", exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit"); ha_warning("Worker %d exited with code %d (%s)\n", exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
} else { } else {
/* check if exited child was in the current children list */ /* check if exited child was is a current child */
if (current_child(exitpid)) { if (child->reloads == 0) {
ha_alert("Current worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit"); if (child->type == 'w')
ha_alert("Current worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
if (status != 0 && status != 130 && status != 143 if (status != 0 && status != 130 && status != 143
&& !(global.tune.options & GTUNE_NOEXIT_ONFAILURE)) { && !(global.tune.options & GTUNE_NOEXIT_ONFAILURE)) {
ha_alert("exit-on-failure: killing every workers with SIGTERM\n"); ha_alert("exit-on-failure: killing every workers with SIGTERM\n");
@ -228,9 +247,10 @@ restart_wait:
mworker_kill(SIGTERM); mworker_kill(SIGTERM);
} }
} else { } else {
ha_warning("Former worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit"); if (child->type == 'w') {
/* TODO: merge children and oldpids list in mworker mode */ ha_warning("Former worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
delete_oldpid(exitpid); delete_oldpid(exitpid);
}
} }
free(child); free(child);
} }