From 3f12887ffa72df1d66f33c2f5d9d83d74df78f52 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Mon, 1 Apr 2019 11:29:59 +0200 Subject: [PATCH] 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. --- include/proto/mworker.h | 3 ++- src/haproxy.c | 27 ++++++++----------- src/mworker.c | 58 +++++++++++++++++++++++++++-------------- 3 files changed, 52 insertions(+), 36 deletions(-) diff --git a/include/proto/mworker.h b/include/proto/mworker.h index 3b3e28066f..02a10deab2 100644 --- a/include/proto/mworker.h +++ b/include/proto/mworker.h @@ -31,6 +31,7 @@ void mworker_pipe_register(); void mworker_cleanlisteners(); -extern int *children; /* store PIDs of children in master workers mode */ +int mworker_child_nb(); + #endif /* PROTO_MWORKER_H_ */ diff --git a/src/haproxy.c b/src/haproxy.c index 77efdd50c9..b2bf558bb0 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -557,7 +557,6 @@ static void get_cur_unixsocket() void mworker_reload() { int next_argc = 0; - int j; char *msg = NULL; struct rlimit limit; struct per_thread_deinit_fct *ptdf; @@ -598,29 +597,27 @@ void mworker_reload() next_argc++; /* 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) goto alloc_error; - /* add -sf * to argv */ - if (children || nb_oldpids > 0) + if (mworker_child_nb() > 0) { + struct mworker_proc *child; + next_argv[next_argc++] = "-sf"; - if (children) { - for (j = 0; j < global.nbproc; next_argc++,j++) { - next_argv[next_argc] = memprintf(&msg, "%d", children[j]); + + list_for_each_entry(child, &proc_list, list) { + if (child->type != 'w' && child->type != 'e') + continue; + next_argv[next_argc] = memprintf(&msg, "%d", child->pid); if (next_argv[next_argc] == NULL) goto alloc_error; 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; /* 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 */ if (!(global.mode & MODE_MWORKER_WAIT)) { - children = calloc(global.nbproc, sizeof(int)); for (proc = 0; proc < global.nbproc; proc++) { ret = fork(); if (ret < 0) { @@ -2854,7 +2850,6 @@ int main(int argc, char **argv) } 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); diff --git a/src/mworker.c b/src/mworker.c index 0d46884f08..0c4ae21b27 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -36,8 +36,6 @@ static int exitcode = -1; -int *children = NULL; /* store PIDs of children in master workers mode */ - /* ----- children processes handling ----- */ /* @@ -46,29 +44,46 @@ int *children = NULL; /* store PIDs of children in master workers mode */ static void mworker_kill(int sig) { - int i; + struct mworker_proc *child; - /* TODO: merge mworker_kill and tell_old_pids for mworker mode */ - tell_old_pids(sig); - if (children) { - for (i = 0; i < global.nbproc; i++) - kill(children[i], sig); + list_for_each_entry(child, &proc_list, list) { + /* careful there, we must be sure that the pid > 0, we don't want to emit a kill -1 */ + if ((child->type == 'w' || child->type == 'e') && (child->reloads == 0) && (child->pid > 0)) + kill(child->pid, sig); } } /* 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++) { - if (children[i] == pid) + list_for_each_entry(child, &proc_list, list) { + if ((child->type == 'w' || child->type == 'e') && (child->reloads == 0) && (child->pid == pid)) return 1; } 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 */ @@ -204,6 +219,7 @@ restart_wait: else status = 255; + /* delete the child from the process list */ list_for_each_entry_safe(child, it, &proc_list, list) { if (child->pid != exitpid) continue; @@ -214,12 +230,15 @@ restart_wait: 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"); } else { - /* check if exited child was in the current children list */ - if (current_child(exitpid)) { - ha_alert("Current worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit"); + /* check if exited child was is a current child */ + if (child->reloads == 0) { + 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 && !(global.tune.options & GTUNE_NOEXIT_ONFAILURE)) { ha_alert("exit-on-failure: killing every workers with SIGTERM\n"); @@ -228,9 +247,10 @@ restart_wait: mworker_kill(SIGTERM); } } else { - ha_warning("Former worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit"); - /* TODO: merge children and oldpids list in mworker mode */ - delete_oldpid(exitpid); + if (child->type == 'w') { + 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); + } } free(child); } -- 2.39.5