From: Valentine Krasnobaeva Date: Thu, 31 Oct 2024 10:44:36 +0000 (+0100) Subject: BUG/MINOR: mworker: do 'program' postparser checks in read_cfg_in_discovery_mode X-Git-Tag: v3.1-dev12~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e9928c306ce4a7612cb4dc4487034bd9be4e0c72;p=thirdparty%2Fhaproxy.git BUG/MINOR: mworker: do 'program' postparser checks in read_cfg_in_discovery_mode cfg_program_postparser() contains 2 parts: - check the combination of MODE_MWORKER and "program" section. if "program" section was parsed, MODE_MWORKER is mandatory; - check "command" keyword, which is mandatory for this section as well. This is more appropriate now, after the master-worker refactoring, do the first part in read_cfg_in_discovery_mode, where we already check the combination of MODE_MWORKER and -S option. We need to do the second part just below, in read_cfg_in_discovery_mode() as well, because it's only the master process, who parses now program section and programs are forked before running postparser functions in step_init_2. Otherwise, mworker_ext_launch_all() will emit a log message, that program is started, but actually nothing has been launched, if 'command' keyword is absent. This not needs to be backported, as related to the master-worker refactoring. --- diff --git a/src/haproxy.c b/src/haproxy.c index e557958632..49b08592a1 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3102,6 +3102,7 @@ static void run_master_in_recovery_mode(int argc, char **argv) static void read_cfg_in_discovery_mode(int argc, char **argv) { struct cfgfile *cfg, *cfg_tmp; + struct mworker_proc *proc; /* load configs in memory and parse only global section (MODE_DISCOVERY) */ global.mode |= MODE_DISCOVERY; @@ -3151,6 +3152,36 @@ static void read_cfg_in_discovery_mode(int argc, char **argv) exit(EXIT_FAILURE); } + /* "progam" sections, if there are any, were alredy parsed only by master + * and programs are forked before calling postparser functions from + * postparser list. So, all checks related to "program" section integrity + * and sections vs MODE_MWORKER combinations should be done here. + */ + list_for_each_entry(proc, &proc_list, list) { + if (proc->options & PROC_O_TYPE_PROG) { + if (!(global.mode & MODE_MWORKER)) { + ha_alert("'program' section is defined in configuration, " + "but master-worker mode (-W) is not enabled.\n"); + exit(EXIT_FAILURE); + } + + if ((proc->reloads == 0) && (proc->command == NULL)) { + if (getenv("HAPROXY_MWORKER_REEXEC") != NULL) { + ha_warning("Master failed to parse new configuration: " + "the program section '%s' lacks a command to launch. " + "It can't start a new worker and launch defined programs. " + "Already running worker and programs " + "will be kept. Please, check program section settings\n", proc->id); + + run_master_in_recovery_mode(argc, argv); + } else { + ha_alert("The program section '%s' lacks a command to launch.\n", proc->id); + exit(EXIT_FAILURE); + } + } + } + } + /* in MODE_CHECK and in MODE_DUMP_CFG we just need to parse the * configuration and exit, see step_init_2() */ diff --git a/src/mworker-prog.c b/src/mworker-prog.c index 4cf0da3cc2..8e6bb3e769 100644 --- a/src/mworker-prog.c +++ b/src/mworker-prog.c @@ -332,31 +332,4 @@ out: } -int cfg_program_postparser() -{ - int err_code = 0; - struct mworker_proc *child; - - if (!(global.mode & MODE_DISCOVERY)) - return err_code; - - list_for_each_entry(child, &proc_list, list) { - if (child->reloads == 0 && (child->options & PROC_O_TYPE_PROG)) { - if (child->command == NULL) { - ha_alert("The program section '%s' lacks a command to launch.\n", child->id); - err_code |= ERR_ALERT | ERR_FATAL; - } - } - } - - if (use_program && !(global.mode & MODE_MWORKER)) { - ha_alert("Can't use a 'program' section without master worker mode.\n"); - err_code |= ERR_ALERT | ERR_FATAL; - } - - return err_code; -} - - REGISTER_CONFIG_SECTION("program", cfg_parse_program, NULL); -REGISTER_CONFIG_POSTPARSER("program", cfg_program_postparser);