MEDIUM: initcall: move STG_REGISTER earlier

The STG_REGISTER init level is used to register known keywords and
protocol stacks. It must be called earlier because some of the init
code already relies on it to be known. For example, "haproxy -vv"
for now is constrained to start very late only because of this.

This patch moves it between STG_LOCK and STG_ALLOC, which is fine as
it's used for static registration.
This commit is contained in:
Willy Tarreau 2022-02-18 14:51:49 +01:00
parent ef301b7556
commit 3ebe4d989c
3 changed files with 12 additions and 7 deletions

View File

@ -213,19 +213,24 @@ and in this execution order:
- STG_PREPARE : used to preset variables, pre-initialize lookup tables and
pre-initialize list heads
- STG_LOCK : used to pre-initialize locks
- STG_REGISTER : used to register static lists such as keywords
- STG_ALLOC : used to allocate the required structures
- STG_POOL : used to create pools
- STG_REGISTER : used to register static lists such as keywords
- STG_INIT : used to initialize subsystems
Each stage is guaranteed that previous stages have successfully completed. This
means that an INITCALL placed at stage STG_REGISTER is guaranteed that all
pools were already created and will be usable. Conversely, an INITCALL placed
at stage STG_PREPARE must not rely on any field that requires preliminary
means that an INITCALL placed at stage STG_INIT is guaranteed that all pools
were already created and will be usable. Conversely, an INITCALL placed at
stage STG_REGISTER must not rely on any field that requires preliminary
allocation nor initialization. A callback cannot rely on other callbacks of the
same stage, as the execution order within a stage is undefined and essentially
depends on the linking order.
The STG_REGISTER level is made for run-time linking of the various modules that
compose the executable. Keywords, protocols and various other elements that are
local known to each compilation unit can will be appended into common lists at
boot time. This is why this call is placed just before STG_ALLOC.
Example: register a very early call to init_log() with no argument, and another
call to cli_register_kw(&cli_kws) much later:

View File

@ -63,9 +63,9 @@
enum init_stage {
STG_PREPARE = 0, // preset variables, tables, list heads
STG_LOCK, // pre-initialize locks
STG_REGISTER, // register static lists (keywords etc)
STG_ALLOC, // allocate required structures
STG_POOL, // create pools
STG_REGISTER, // register static lists (keywords etc)
STG_INIT, // subsystems normal initialization
STG_SIZE // size of the stages array, must be last
};
@ -200,9 +200,9 @@ __attribute__((constructor)) static void __initcb_##linenum() \
/* Declare all initcall sections here */
DECLARE_INIT_SECTION(STG_PREPARE);
DECLARE_INIT_SECTION(STG_LOCK);
DECLARE_INIT_SECTION(STG_REGISTER);
DECLARE_INIT_SECTION(STG_ALLOC);
DECLARE_INIT_SECTION(STG_POOL);
DECLARE_INIT_SECTION(STG_REGISTER);
DECLARE_INIT_SECTION(STG_INIT);
// for use in the main haproxy.c file

View File

@ -2906,9 +2906,9 @@ int main(int argc, char **argv)
/* process all initcalls in order of potential dependency */
RUN_INITCALLS(STG_PREPARE);
RUN_INITCALLS(STG_LOCK);
RUN_INITCALLS(STG_REGISTER);
RUN_INITCALLS(STG_ALLOC);
RUN_INITCALLS(STG_POOL);
RUN_INITCALLS(STG_REGISTER);
RUN_INITCALLS(STG_INIT);
init(argc, argv);