From: William Lallemand Date: Fri, 5 Jun 2020 12:08:41 +0000 (+0200) Subject: BUG/MEDIUM: mworker: fix the reload with an -- option X-Git-Tag: v2.1.6~3 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=29e710624583d71e7eeae63a6ea7734006a1ea57;p=haproxy-2.1.git BUG/MEDIUM: mworker: fix the reload with an -- option When HAProxy is started with a '--' option, all following parameters are considered configuration files. You can't add new options after a '--'. The current reload system of the master-worker adds extra options at the end of the arguments list. Which is a problem if HAProxy was started wih '--'. This patch fixes the issue by copying the new option at the beginning of the arguments list instead of the end. This patch must be backported as far as 1.8. (cherry picked from commit 0041741ef7253fcad2fc98f0b2a9968fb4af3574) [wla: context edit] Signed-off-by: William Lallemand --- diff --git a/src/haproxy.c b/src/haproxy.c index 15b8b1f..d97c1f3 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -231,7 +231,7 @@ char localpeer[MAX_HOSTNAME_LEN]; */ int shut_your_big_mouth_gcc_int = 0; -static char **next_argv = NULL; +static char **old_argv = NULL; /* previous argv but cleaned up */ struct list proc_list = LIST_HEAD_INIT(proc_list); @@ -764,7 +764,10 @@ static void get_cur_unixsocket() */ void mworker_reload() { + char **next_argv = NULL; + int old_argc = 0; /* previous number of argument */ int next_argc = 0; + int i = 0; char *msg = NULL; struct rlimit limit; struct per_thread_deinit_fct *ptdf; @@ -808,14 +811,19 @@ void mworker_reload() } /* compute length */ - while (next_argv[next_argc]) - next_argc++; + while (old_argv[old_argc]) + old_argc++; /* 1 for haproxy -sf, 2 for -x /socket */ - next_argv = realloc(next_argv, (next_argc + 1 + 2 + mworker_child_nb() + nb_oldpids + 1) * sizeof(char *)); + next_argv = calloc(old_argc + 1 + 2 + mworker_child_nb() + nb_oldpids + 1, sizeof(char *)); if (next_argv == NULL) goto alloc_error; + /* copy the program name */ + next_argv[next_argc++] = old_argv[0]; + + /* insert the new options just after argv[0] in case we have a -- */ + /* add -sf * to argv */ if (mworker_child_nb() > 0) { struct mworker_proc *child; @@ -825,24 +833,21 @@ void mworker_reload() list_for_each_entry(child, &proc_list, list) { if (!(child->options & (PROC_O_TYPE_WORKER|PROC_O_TYPE_PROG)) || child->pid <= -1 ) continue; - next_argv[next_argc] = memprintf(&msg, "%d", child->pid); - if (next_argv[next_argc] == NULL) + if ((next_argv[next_argc++] = memprintf(&msg, "%d", child->pid)) == NULL) goto alloc_error; msg = NULL; - next_argc++; } } - - next_argv[next_argc] = NULL; - /* add the -x option with the stat socket */ if (cur_unixsocket) { - next_argv[next_argc++] = "-x"; next_argv[next_argc++] = (char *)cur_unixsocket; - next_argv[next_argc++] = NULL; } + /* copy the previous options */ + for (i = 1; i < old_argc; i++) + next_argv[next_argc++] = old_argv[i]; + ha_warning("Reexecuting Master process\n"); signal(SIGPROF, SIG_IGN); execvp(next_argv[0], next_argv); @@ -851,6 +856,8 @@ void mworker_reload() return; alloc_error: + free(next_argv); + next_argv = NULL; ha_warning("Failed to reexecute the master process [%d]: Cannot allocate memory\n", pid); return; } @@ -1656,8 +1663,8 @@ static void init(int argc, char **argv) int ideal_maxconn; global.mode = MODE_STARTING; - next_argv = copy_argv(argc, argv); - if (!next_argv) { + old_argv = copy_argv(argc, argv); + if (!old_argv) { ha_alert("failed to copy argv.\n"); exit(1); }