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.
This commit is contained in:
Valentine Krasnobaeva 2024-10-31 11:44:36 +01:00 committed by William Lallemand
parent 1767196d5b
commit e9928c306c
2 changed files with 31 additions and 27 deletions

View File

@ -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()
*/

View File

@ -332,31 +332,4 @@ int cfg_parse_program(const char *file, int linenum, char **args, int kwm)
}
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);