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.2-dev9~150 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0041741ef7253fcad2fc98f0b2a9968fb4af3574;p=thirdparty%2Fhaproxy.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. --- diff --git a/src/haproxy.c b/src/haproxy.c index 80cee38ea1..92a54bab0f 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -226,7 +226,7 @@ const struct linger nolinger = { .l_onoff = 1, .l_linger = 0 }; char hostname[MAX_HOSTNAME_LEN]; char localpeer[MAX_HOSTNAME_LEN]; -static char **next_argv = NULL; +static char **old_argv = NULL; /* previous argv but cleaned up */ struct list proc_list = LIST_HEAD_INIT(proc_list); @@ -755,7 +755,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; @@ -799,14 +802,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; @@ -816,24 +824,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); @@ -842,6 +847,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; } @@ -1711,8 +1718,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); }