MINOR: init: extract args parsing to their own function

The cmdline argument parsing was performed quite late, which prevents
from retrieving elements that can be used to initialize the pools and
certain sensitive areas. The goal is to improve this by parsing command
line arguments right after the early init stage. This is possible
because the cmdline parser already does very little beyond retrieving
config elements that are used later.

Doing so requires to move the parser code to a separate function and
to externalize a few variables out of the function as they're used
later in the boot process, in the original function.

This patch creates init_args() but doesn't move it upfront yet, it's
still executed just before init(), which essentially corresponds to
what was done before (only the trash buffers, ACLs and Lua were
initialized earlier and are not needed for this).

The rest is not modified and as expected no change is observed.

Note that the diff doesn't to justice to the change as it makes it
look like the early init() code was moved to a new function after
the function was renamed, while in fact it's clearly the parser
itself which moved.
This commit is contained in:
Willy Tarreau 2022-02-17 18:10:36 +01:00
parent 34527d5354
commit 392524d222

View File

@ -218,6 +218,9 @@ int jobs = 0; /* number of active jobs (conns, listeners, active tasks, ...) *
int unstoppable_jobs = 0; /* number of active jobs that can't be stopped during a soft stop */ int unstoppable_jobs = 0; /* number of active jobs that can't be stopped during a soft stop */
int active_peers = 0; /* number of active peers (connection attempts and connected) */ int active_peers = 0; /* number of active peers (connection attempts and connected) */
int connected_peers = 0; /* number of connected peers (verified ones) */ int connected_peers = 0; /* number of connected peers (verified ones) */
int arg_mode = 0; /* MODE_DEBUG etc as passed on command line ... */
char *change_dir = NULL; /* set when -C is passed */
char *check_condition = NULL; /* check condition passed to -cc */
/* Here we store information about the pids of the processes we may pause /* Here we store information about the pids of the processes we may pause
* or kill. We will send them a signal every 10 ms until we can bind to all * or kill. We will send them a signal every 10 ms until we can bind to all
@ -1529,13 +1532,6 @@ static void init_early(int argc, char **argv)
} }
#endif #endif
/* keep a copy of original arguments for the master process */
old_argv = copy_argv(argc, argv);
if (!old_argv) {
ha_alert("failed to copy argv.\n");
exit(EXIT_FAILURE);
}
/* extract the program name from argv[0], it will be used for the logs /* extract the program name from argv[0], it will be used for the logs
* and error messages. * and error messages.
*/ */
@ -1553,34 +1549,14 @@ static void init_early(int argc, char **argv)
chunk_initlen(&global.log_tag, progname, len, len); chunk_initlen(&global.log_tag, progname, len, len);
} }
/* /* handles program arguments. Very minimal parsing is performed, variables are
* This function initializes all the necessary variables. It only returns * fed with some values, and lists are completed with other ones. In case of
* if everything is OK. If something fails, it exits. * error, it will exit.
*/ */
static void init(int argc, char **argv) static void init_args(int argc, char **argv)
{ {
int arg_mode = 0; /* MODE_DEBUG, ... */
char *cfg_pidfile = NULL;
int err_code = 0;
char *err_msg = NULL;
struct wordlist *wl;
char *progname = global.log_tag.area; char *progname = global.log_tag.area;
char *change_dir = NULL; char *err_msg = NULL;
struct proxy *px;
struct post_check_fct *pcf;
int ideal_maxconn;
char *check_condition = NULL;
if (!init_trash_buffers(1)) {
ha_alert("failed to initialize trash buffers.\n");
exit(1);
}
if (init_acl() != 0)
exit(1);
/* Initialise lua. */
hlua_init();
/* pre-fill in the global tuning options before we let the cmdline /* pre-fill in the global tuning options before we let the cmdline
* change them. * change them.
@ -1612,6 +1588,14 @@ static void init(int argc, char **argv)
#endif #endif
global.tune.options |= GTUNE_STRICT_LIMITS; global.tune.options |= GTUNE_STRICT_LIMITS;
/* keep a copy of original arguments for the master process */
old_argv = copy_argv(argc, argv);
if (!old_argv) {
ha_alert("failed to copy argv.\n");
exit(EXIT_FAILURE);
}
/* skip program name and start */
argc--; argv++; argc--; argv++;
while (argc > 0) { while (argc > 0) {
char *flag; char *flag;
@ -1806,7 +1790,13 @@ static void init(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'p' : cfg_pidfile = *argv; break; case 'p' :
free(global.pidfile);
if ((global.pidfile = strdup(*argv)) == NULL) {
ha_alert("Cannot allocate memory for pidfile.\n");
exit(EXIT_FAILURE);
}
break;
default: usage(progname); default: usage(progname);
} }
} }
@ -1815,6 +1805,32 @@ static void init(int argc, char **argv)
usage(progname); usage(progname);
argv++; argc--; argv++; argc--;
} }
free(err_msg);
}
/*
* This function initializes all the necessary variables. It only returns
* if everything is OK. If something fails, it exits.
*/
static void init(int argc, char **argv)
{
char *progname = global.log_tag.area;
int err_code = 0;
struct wordlist *wl;
struct proxy *px;
struct post_check_fct *pcf;
int ideal_maxconn;
if (!init_trash_buffers(1)) {
ha_alert("failed to initialize trash buffers.\n");
exit(1);
}
if (init_acl() != 0)
exit(1);
/* Initialise lua. */
hlua_init();
global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
| MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING | MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING
@ -2144,11 +2160,6 @@ static void init(int argc, char **argv)
global.maxsock += p->peers_fe->maxconn; global.maxsock += p->peers_fe->maxconn;
} }
if (cfg_pidfile) {
free(global.pidfile);
global.pidfile = strdup(cfg_pidfile);
}
/* Now we want to compute the maxconn and possibly maxsslconn values. /* Now we want to compute the maxconn and possibly maxsslconn values.
* It's a bit tricky. Maxconn defaults to the pre-computed value based * It's a bit tricky. Maxconn defaults to the pre-computed value based
* on rlim_fd_cur and the number of FDs in use due to the configuration, * on rlim_fd_cur and the number of FDs in use due to the configuration,
@ -2443,8 +2454,6 @@ static void init(int argc, char **argv)
if (!hlua_post_init()) if (!hlua_post_init())
exit(1); exit(1);
free(err_msg);
} }
void deinit(void) void deinit(void)
@ -2937,6 +2946,9 @@ int main(int argc, char **argv)
RUN_INITCALLS(STG_POOL); RUN_INITCALLS(STG_POOL);
RUN_INITCALLS(STG_INIT); RUN_INITCALLS(STG_INIT);
/* handles argument parsing */
init_args(argc, argv);
/* this is the late init where the config is parsed */ /* this is the late init where the config is parsed */
init(argc, argv); init(argc, argv);