]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: init: initialize the trash earlier
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Jul 2023 16:42:53 +0000 (18:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 8 Sep 2023 14:25:19 +0000 (16:25 +0200)
More and more utility functions rely on the trash while most of the init
code doesn't have access to it because it's initialized very late (in
PRE_CHECK for the initial one). It's a pool, and it purposely supports
being reallocated, so let's initialize it in STG_POOL so that early
STG_INIT code can at least use it.

doc/internals/api/initcalls.txt
src/chunk.c
src/haproxy.c

index 30d8737206eb5934489a7dfa0cac18eba67f2ecf..a341edc1dba4bdae9af0e36997fcf310ed1da734 100644 (file)
@@ -122,10 +122,11 @@ make sure to respect this ordering when adding new ones.
   parsing and where the initialization should continue in the configuration
   check.
   It could be used for example to generate a proxy with multiple servers using
-  the configuration parser itself. At this step the trash buffers are allocated.
-  Threads are not yet started so no protection is required. The function is
-  expected to return non-zero on success, or zero on failure. A failure will make
-  the process emit a succinct error message and immediately exit.
+  the configuration parser itself. At this step the final trash buffers are
+  allocated. Threads are not yet started so no protection is required. The
+  function is expected to return non-zero on success, or zero on failure. A
+  failure will make the process emit a succinct error message and immediately
+  exit.
 
 - void hap_register_post_check(int (*fct)())
 
@@ -244,6 +245,11 @@ 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.
 
+Note that trash is needed in various functions. Trash is a pool and is
+allocated during STG_POOL, so it's not permitted to use it before STG_INIT,
+where it will only use the default size, and may be reallocated later with a
+different size.
+
 Example: register a very early call to init_log() with no argument, and another
          call to cli_register_kw(&cli_kws) much later:
 
index b9728e1c9110361cc86fdf2126b88654471186cf..c5b74fc5e73098ea1b3939cbcc9f8865d047fb0f 100644 (file)
@@ -98,6 +98,15 @@ int init_trash_buffers(int first)
        return 1;
 }
 
+/* This is called during STG_POOL to allocate trash buffers early. They will
+ * be reallocated later once their final size is known. It returns 0 if an
+ * error occurred.
+ */
+static int alloc_early_trash(void)
+{
+       return init_trash_buffers(1);
+}
+
 /*
  * Does an snprintf() at the beginning of chunk <chk>, respecting the limit of
  * at most chk->size chars. If the chk->len is over, nothing is added. Returns
@@ -289,6 +298,7 @@ int chunk_strcasecmp(const struct buffer *chk, const char *str)
        return diff;
 }
 
+INITCALL0(STG_POOL, alloc_early_trash);
 REGISTER_PER_THREAD_ALLOC(alloc_trash_buffers_per_thread);
 REGISTER_PER_THREAD_FREE(free_trash_buffers_per_thread);
 REGISTER_POST_DEINIT(free_trash_buffers_per_thread);
index 1b5be885721321ba3b6dcc30141cf23f58751ad4..18308bc59ad217432b0bd2d7b8d436fbdf5bde8f 100644 (file)
@@ -1976,11 +1976,6 @@ static void init(int argc, char **argv)
 
        startup_logs_init();
 
-       if (!init_trash_buffers(1)) {
-               ha_alert("failed to initialize trash buffers.\n");
-               exit(1);
-       }
-
        if (init_acl() != 0)
                exit(1);
 
@@ -3303,6 +3298,13 @@ int main(int argc, char **argv)
 
        RUN_INITCALLS(STG_ALLOC);
        RUN_INITCALLS(STG_POOL);
+
+       /* some code really needs to have the trash properly allocated */
+       if (!trash.area) {
+               ha_alert("failed to initialize trash buffers.\n");
+               exit(1);
+       }
+
        RUN_INITCALLS(STG_INIT);
 
        /* this is the late init where the config is parsed */