Coverage Report

Created: 2026-07-12 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/haproxy/src/init.c
Line
Count
Source
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <haproxy/init.h>
5
#include <haproxy/list.h>
6
7
/* These functions are called just before a config validity check, which mean
8
 * they are suited to use them in case we need to generate part of the
9
 * configuration. It could be used for example to generate a proxy with
10
 * multiple servers using the configuration parser itself. At this step the
11
 * trash buffers are allocated.
12
 * The functions must return 0 on success, or a combination
13
 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
14
 * and immediate exit, so the function must have emitted any useful error.
15
 */
16
struct list pre_check_list = LIST_HEAD_INIT(pre_check_list);
17
18
/* These functions are called just after the point where the program exits
19
 * after a config validity check, so they are generally suited for resource
20
 * allocation and slow initializations that should be skipped during basic
21
 * config checks. The functions must return 0 on success, or a combination
22
 * of ERR_* flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause
23
 * and immediate exit, so the function must have emitted any useful error.
24
 */
25
struct list post_check_list = LIST_HEAD_INIT(post_check_list);
26
27
/* These functions are called for each proxy just after the config validity
28
 * check. The functions must return 0 on success, or a combination of ERR_*
29
 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
30
 * exit, so the function must have emitted any useful error.
31
 */
32
struct list post_proxy_check_list = LIST_HEAD_INIT(post_proxy_check_list);
33
34
/* These functions are called for each server just after the config validity
35
 * check. The functions must return 0 on success, or a combination of ERR_*
36
 * flags (ERR_WARN, ERR_ABORT, ERR_FATAL, ...). The 2 latter cause and immediate
37
 * exit, so the function must have emitted any useful error.
38
 */
39
struct list post_server_check_list = LIST_HEAD_INIT(post_server_check_list);
40
41
/* These functions are called for each thread just after the thread creation
42
 * and before running the init functions. They should be used to do per-thread
43
 * (re-)allocations that are needed by subsequent functoins. They must return 0
44
 * if an error occurred. */
45
struct list per_thread_alloc_list = LIST_HEAD_INIT(per_thread_alloc_list);
46
47
/* These functions are called for each thread just after the thread creation
48
 * and before running the scheduler. They should be used to do per-thread
49
 * initializations. They must return 0 if an error occurred. */
50
struct list per_thread_init_list = LIST_HEAD_INIT(per_thread_init_list);
51
52
/* These functions are called when freeing the global sections at the end of
53
 * deinit, after everything is stopped. They don't return anything. They should
54
 * not release shared resources that are possibly used by other deinit
55
 * functions, only close/release what is private. Use the per_thread_free_list
56
 * to release shared resources.
57
 */
58
struct list post_deinit_list = LIST_HEAD_INIT(post_deinit_list);
59
60
/* These functions after everything is stopped, right before exit(), for the master
61
 * process when haproxy was started in master-worker mode. They don't return anything.
62
 */
63
struct list post_deinit_master_list = LIST_HEAD_INIT(post_deinit_master_list);
64
65
/* These functions are called when freeing a proxy during the deinit, after
66
 * everything isg stopped. They don't return anything. They should not release
67
 * the proxy itself or any shared resources that are possibly used by other
68
 * deinit functions, only close/release what is private.
69
 */
70
struct list proxy_deinit_list = LIST_HEAD_INIT(proxy_deinit_list);
71
72
/* These functions are called when freeing a server during the deinit, after
73
 * everything isg stopped. They don't return anything. They should not release
74
 * the proxy itself or any shared resources that are possibly used by other
75
 * deinit functions, only close/release what is private.
76
 */
77
struct list server_deinit_list = LIST_HEAD_INIT(server_deinit_list);
78
79
/* These functions are called when freeing the global sections at the end of
80
 * deinit, after the thread deinit functions, to release unneeded memory
81
 * allocations. They don't return anything, and they work in best effort mode
82
 * as their sole goal is to make valgrind mostly happy.
83
 */
84
struct list per_thread_free_list = LIST_HEAD_INIT(per_thread_free_list);
85
86
/* These functions are called for each thread just after the scheduler loop and
87
 * before exiting the thread. They don't return anything and, as for post-deinit
88
 * functions, they work in best effort mode as their sole goal is to make
89
 * valgrind mostly happy. */
90
struct list per_thread_deinit_list = LIST_HEAD_INIT(per_thread_deinit_list);
91
92
/* location of current INITCALL declaration being processed, or NULL */
93
const struct initcall *caller_initcall = NULL;
94
const char *caller_file = NULL;
95
int caller_line = 0;
96
97
/* used to register some initialization functions to call before the checks. */
98
void hap_register_pre_check(int (*fct)())
99
0
{
100
0
  struct pre_check_fct *b;
101
102
0
  b = calloc(1, sizeof(*b));
103
0
  if (!b) {
104
0
    fprintf(stderr, "out of memory\n");
105
0
    exit(1);
106
0
  }
107
0
  b->fct = fct;
108
0
  LIST_APPEND(&pre_check_list, &b->list);
109
0
}
110
111
/* used to register some initialization functions to call after the checks. */
112
void hap_register_post_check(int (*fct)())
113
0
{
114
0
  struct post_check_fct *b;
115
116
0
  b = calloc(1, sizeof(*b));
117
0
  if (!b) {
118
0
    fprintf(stderr, "out of memory\n");
119
0
    exit(1);
120
0
  }
121
0
  b->fct = fct;
122
0
  LIST_APPEND(&post_check_list, &b->list);
123
0
}
124
125
/* used to register some initialization functions to call for each proxy after
126
 * the checks.
127
 */
128
void hap_register_post_proxy_check(int (*fct)(struct proxy *))
129
0
{
130
0
  struct post_proxy_check_fct *b;
131
132
0
  b = calloc(1, sizeof(*b));
133
0
  if (!b) {
134
0
    fprintf(stderr, "out of memory\n");
135
0
    exit(1);
136
0
  }
137
0
  b->fct = fct;
138
0
  LIST_APPEND(&post_proxy_check_list, &b->list);
139
0
}
140
141
/* used to register some initialization functions to call for each server after
142
 * the checks.
143
 */
144
void hap_register_post_server_check(int (*fct)(struct server *))
145
0
{
146
0
  struct post_server_check_fct *b;
147
148
0
  b = calloc(1, sizeof(*b));
149
0
  if (!b) {
150
0
    fprintf(stderr, "out of memory\n");
151
0
    exit(1);
152
0
  }
153
0
  b->fct = fct;
154
0
  LIST_APPEND(&post_server_check_list, &b->list);
155
0
}
156
157
/* used to register some de-initialization functions to call after everything
158
 * has stopped.
159
 */
160
void hap_register_post_deinit(void (*fct)())
161
0
{
162
0
  struct post_deinit_fct *b;
163
164
0
  b = calloc(1, sizeof(*b));
165
0
  if (!b) {
166
0
    fprintf(stderr, "out of memory\n");
167
0
    exit(1);
168
0
  }
169
0
  b->fct = fct;
170
0
  LIST_APPEND(&post_deinit_list, &b->list);
171
0
}
172
173
/* used to register some de-initialization functions to call after everything
174
 * has stopped, but only for the master process (when started in master-worker mode).
175
 */
176
void hap_register_post_deinit_master(void (*fct)())
177
0
{
178
0
  struct post_deinit_fct *b;
179
180
0
  b = calloc(1, sizeof(*b));
181
0
  if (!b) {
182
0
    fprintf(stderr, "out of memory\n");
183
0
    exit(1);
184
0
  }
185
0
  b->fct = fct;
186
0
  LIST_APPEND(&post_deinit_master_list, &b->list);
187
0
}
188
189
/* used to register some per proxy de-initialization functions to call after
190
 * everything has stopped.
191
 */
192
void hap_register_proxy_deinit(void (*fct)(struct proxy *))
193
0
{
194
0
  struct proxy_deinit_fct *b;
195
196
0
  b = calloc(1, sizeof(*b));
197
0
  if (!b) {
198
0
    fprintf(stderr, "out of memory\n");
199
0
    exit(1);
200
0
  }
201
0
  b->fct = fct;
202
0
  LIST_APPEND(&proxy_deinit_list, &b->list);
203
0
}
204
205
/* used to register some per server de-initialization functions to call after
206
 * everything has stopped.
207
 */
208
void hap_register_server_deinit(void (*fct)(struct server *))
209
0
{
210
0
  struct server_deinit_fct *b;
211
212
0
  b = calloc(1, sizeof(*b));
213
0
  if (!b) {
214
0
    fprintf(stderr, "out of memory\n");
215
0
    exit(1);
216
0
  }
217
0
  b->fct = fct;
218
0
  LIST_APPEND(&server_deinit_list, &b->list);
219
0
}
220
221
/* used to register some allocation functions to call for each thread. */
222
void hap_register_per_thread_alloc(int (*fct)())
223
0
{
224
0
  struct per_thread_alloc_fct *b;
225
226
0
  b = calloc(1, sizeof(*b));
227
0
  if (!b) {
228
0
    fprintf(stderr, "out of memory\n");
229
0
    exit(1);
230
0
  }
231
0
  b->fct = fct;
232
0
  LIST_APPEND(&per_thread_alloc_list, &b->list);
233
0
}
234
235
/* used to register some initialization functions to call for each thread. */
236
void hap_register_per_thread_init(int (*fct)())
237
0
{
238
0
  struct per_thread_init_fct *b;
239
240
0
  b = calloc(1, sizeof(*b));
241
0
  if (!b) {
242
0
    fprintf(stderr, "out of memory\n");
243
0
    exit(1);
244
0
  }
245
0
  b->fct = fct;
246
0
  LIST_APPEND(&per_thread_init_list, &b->list);
247
0
}
248
249
/* used to register some de-initialization functions to call for each thread. */
250
void hap_register_per_thread_deinit(void (*fct)())
251
0
{
252
0
  struct per_thread_deinit_fct *b;
253
254
0
  b = calloc(1, sizeof(*b));
255
0
  if (!b) {
256
0
    fprintf(stderr, "out of memory\n");
257
0
    exit(1);
258
0
  }
259
0
  b->fct = fct;
260
0
  LIST_APPEND(&per_thread_deinit_list, &b->list);
261
0
}
262
263
/* used to register some free functions to call for each thread. */
264
void hap_register_per_thread_free(void (*fct)())
265
0
{
266
0
  struct per_thread_free_fct *b;
267
268
0
  b = calloc(1, sizeof(*b));
269
0
  if (!b) {
270
0
    fprintf(stderr, "out of memory\n");
271
0
    exit(1);
272
0
  }
273
0
  b->fct = fct;
274
0
  LIST_APPEND(&per_thread_free_list, &b->list);
275
0
}