blob: c653fb49d6612ae4b6866d57d2e3776368cc2d48 [file] [log] [blame]
Willy Tarreau36b9e222018-11-11 15:19:52 +01001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <netdb.h>
5#include <ctype.h>
6#include <pwd.h>
7#include <grp.h>
8#include <errno.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <fcntl.h>
12#include <unistd.h>
13
Eric Salama7cea6062020-10-02 11:58:19 +020014#include <haproxy/buf.h>
Willy Tarreau6be78492020-06-05 00:00:29 +020015#include <haproxy/cfgparse.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020016#ifdef USE_CPU_AFFINITY
Amaury Denoyellec90932b2021-04-14 16:16:03 +020017#include <haproxy/cpuset.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020018#endif
Willy Tarreau0a3bd392020-06-04 08:52:38 +020019#include <haproxy/compression.h>
Willy Tarreaudfd3de82020-06-04 23:46:14 +020020#include <haproxy/global.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020021#include <haproxy/log.h>
Dragan Dosen13cd54c2020-06-18 18:24:05 +020022#include <haproxy/peers.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020023#include <haproxy/tools.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010024
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010025/* some keywords that are still being parsed using strcmp() and are not
26 * registered anywhere. They are used as suggestions for mistyped words.
27 */
28static const char *common_kw_list[] = {
29 "global", "daemon", "master-worker", "noepoll", "nokqueue",
30 "noevports", "nopoll", "busy-polling", "set-dumpable",
31 "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
32 "nogetaddrinfo", "noreuseport", "quiet", "zero-warning",
33 "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept",
34 "tune.chksize", "tune.recv_enough", "tune.buffers.limit",
35 "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite",
36 "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server",
37 "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize",
38 "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr",
39 "tune.comp.maxlevel", "tune.pattern.cache-size", "uid", "gid",
40 "external-check", "user", "group", "nbproc", "nbthread", "maxconn",
41 "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
42 "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n",
43 "chroot", "description", "node", "pidfile", "unix-bind", "log",
44 "log-send-hostname", "server-state-base", "server-state-file",
45 "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv",
46 "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer",
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +010047 "numa-cpu-mapping", "defaults", "listen", "frontend", "backend",
48 "peers", "resolvers",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010049 NULL /* must be last */
50};
51
Willy Tarreau36b9e222018-11-11 15:19:52 +010052/*
53 * parse a line in a <global> section. Returns the error code, 0 if OK, or
54 * any combination of :
55 * - ERR_ABORT: must abort ASAP
56 * - ERR_FATAL: we can continue parsing but not start the service
57 * - ERR_WARN: a warning has been emitted
58 * - ERR_ALERT: an alert has been emitted
59 * Only the two first ones can stop processing, the two others are just
60 * indicators.
61 */
62int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
63{
64 int err_code = 0;
65 char *errmsg = NULL;
66
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010067 if (strcmp(args[0], "global") == 0) { /* new section */
Willy Tarreau36b9e222018-11-11 15:19:52 +010068 /* no option, nothing special to do */
69 alertif_too_many_args(0, file, linenum, args, &err_code);
70 goto out;
71 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010072 else if (strcmp(args[0], "daemon") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010073 if (alertif_too_many_args(0, file, linenum, args, &err_code))
74 goto out;
75 global.mode |= MODE_DAEMON;
76 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010077 else if (strcmp(args[0], "master-worker") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010078 if (alertif_too_many_args(1, file, linenum, args, &err_code))
79 goto out;
80 if (*args[1]) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010081 if (strcmp(args[1], "no-exit-on-failure") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010082 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
83 } else {
84 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
85 err_code |= ERR_ALERT | ERR_FATAL;
86 goto out;
87 }
88 }
89 global.mode |= MODE_MWORKER;
90 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010091 else if (strcmp(args[0], "noepoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010092 if (alertif_too_many_args(0, file, linenum, args, &err_code))
93 goto out;
94 global.tune.options &= ~GTUNE_USE_EPOLL;
95 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010096 else if (strcmp(args[0], "nokqueue") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010097 if (alertif_too_many_args(0, file, linenum, args, &err_code))
98 goto out;
99 global.tune.options &= ~GTUNE_USE_KQUEUE;
100 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100101 else if (strcmp(args[0], "noevports") == 0) {
Emmanuel Hocdet0ba4f482019-04-08 16:53:32 +0000102 if (alertif_too_many_args(0, file, linenum, args, &err_code))
103 goto out;
104 global.tune.options &= ~GTUNE_USE_EVPORTS;
105 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100106 else if (strcmp(args[0], "nopoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100107 if (alertif_too_many_args(0, file, linenum, args, &err_code))
108 goto out;
109 global.tune.options &= ~GTUNE_USE_POLL;
110 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100111 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100112 if (alertif_too_many_args(0, file, linenum, args, &err_code))
113 goto out;
114 if (kwm == KWM_NO)
115 global.tune.options &= ~GTUNE_BUSY_POLLING;
116 else
117 global.tune.options |= GTUNE_BUSY_POLLING;
118 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100119 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200120 if (alertif_too_many_args(0, file, linenum, args, &err_code))
121 goto out;
122 if (kwm == KWM_NO)
123 global.tune.options &= ~GTUNE_SET_DUMPABLE;
124 else
125 global.tune.options |= GTUNE_SET_DUMPABLE;
126 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100127 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100128 if (alertif_too_many_args(0, file, linenum, args, &err_code))
129 goto out;
130 if (kwm == KWM_NO)
131 global.tune.options &= ~GTUNE_INSECURE_FORK;
132 else
133 global.tune.options |= GTUNE_INSECURE_FORK;
134 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100135 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100136 if (alertif_too_many_args(0, file, linenum, args, &err_code))
137 goto out;
138 if (kwm == KWM_NO)
139 global.tune.options &= ~GTUNE_INSECURE_SETUID;
140 else
141 global.tune.options |= GTUNE_INSECURE_SETUID;
142 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100143 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100144 if (alertif_too_many_args(0, file, linenum, args, &err_code))
145 goto out;
146 global.tune.options &= ~GTUNE_USE_SPLICE;
147 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100148 else if (strcmp(args[0], "nogetaddrinfo") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100149 if (alertif_too_many_args(0, file, linenum, args, &err_code))
150 goto out;
151 global.tune.options &= ~GTUNE_USE_GAI;
152 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100153 else if (strcmp(args[0], "noreuseport") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100154 if (alertif_too_many_args(0, file, linenum, args, &err_code))
155 goto out;
156 global.tune.options &= ~GTUNE_USE_REUSEPORT;
157 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100158 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100159 if (alertif_too_many_args(0, file, linenum, args, &err_code))
160 goto out;
161 global.mode |= MODE_QUIET;
162 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100163 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200164 if (alertif_too_many_args(0, file, linenum, args, &err_code))
165 goto out;
166 global.mode |= MODE_ZERO_WARNING;
167 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100168 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100169 if (alertif_too_many_args(1, file, linenum, args, &err_code))
170 goto out;
171 if (global.tune.runqueue_depth != 0) {
172 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
173 err_code |= ERR_ALERT;
174 goto out;
175 }
176 if (*(args[1]) == 0) {
177 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
178 err_code |= ERR_ALERT | ERR_FATAL;
179 goto out;
180 }
181 global.tune.runqueue_depth = atol(args[1]);
182
183 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100184 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100185 if (alertif_too_many_args(1, file, linenum, args, &err_code))
186 goto out;
187 if (global.tune.maxpollevents != 0) {
188 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
189 err_code |= ERR_ALERT;
190 goto out;
191 }
192 if (*(args[1]) == 0) {
193 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
194 err_code |= ERR_ALERT | ERR_FATAL;
195 goto out;
196 }
197 global.tune.maxpollevents = atol(args[1]);
198 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100199 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200200 long max;
201
Willy Tarreau36b9e222018-11-11 15:19:52 +0100202 if (alertif_too_many_args(1, file, linenum, args, &err_code))
203 goto out;
204 if (global.tune.maxaccept != 0) {
205 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
206 err_code |= ERR_ALERT;
207 goto out;
208 }
209 if (*(args[1]) == 0) {
210 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
211 err_code |= ERR_ALERT | ERR_FATAL;
212 goto out;
213 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200214 max = atol(args[1]);
215 if (/*max < -1 || */max > INT_MAX) {
216 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
217 err_code |= ERR_ALERT | ERR_FATAL;
218 goto out;
219 }
220 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100221 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100222 else if (strcmp(args[0], "tune.chksize") == 0) {
Christopher Fauletf8c869b2020-11-25 17:33:03 +0100223 ha_warning("parsing [%s:%d]: the option '%s' is deprecated and will be removed in next version.\n",
224 file, linenum, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100225 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100226 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100227 if (alertif_too_many_args(1, file, linenum, args, &err_code))
228 goto out;
229 if (*(args[1]) == 0) {
230 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
231 err_code |= ERR_ALERT | ERR_FATAL;
232 goto out;
233 }
234 global.tune.recv_enough = atol(args[1]);
235 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100236 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100237 if (alertif_too_many_args(1, file, linenum, args, &err_code))
238 goto out;
239 if (*(args[1]) == 0) {
240 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
241 err_code |= ERR_ALERT | ERR_FATAL;
242 goto out;
243 }
244 global.tune.buf_limit = atol(args[1]);
245 if (global.tune.buf_limit) {
246 if (global.tune.buf_limit < 3)
247 global.tune.buf_limit = 3;
248 if (global.tune.buf_limit <= global.tune.reserved_bufs)
249 global.tune.buf_limit = global.tune.reserved_bufs + 1;
250 }
251 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100252 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100253 if (alertif_too_many_args(1, file, linenum, args, &err_code))
254 goto out;
255 if (*(args[1]) == 0) {
256 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
257 err_code |= ERR_ALERT | ERR_FATAL;
258 goto out;
259 }
260 global.tune.reserved_bufs = atol(args[1]);
261 if (global.tune.reserved_bufs < 2)
262 global.tune.reserved_bufs = 2;
263 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
264 global.tune.buf_limit = global.tune.reserved_bufs + 1;
265 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100266 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100267 if (alertif_too_many_args(1, file, linenum, args, &err_code))
268 goto out;
269 if (*(args[1]) == 0) {
270 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
271 err_code |= ERR_ALERT | ERR_FATAL;
272 goto out;
273 }
274 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100275 /* round it up to support a two-pointer alignment at the end */
276 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100277 if (global.tune.bufsize <= 0) {
278 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
279 err_code |= ERR_ALERT | ERR_FATAL;
280 goto out;
281 }
282 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100283 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100284 if (alertif_too_many_args(1, file, linenum, args, &err_code))
285 goto out;
286 if (*(args[1]) == 0) {
287 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
288 err_code |= ERR_ALERT | ERR_FATAL;
289 goto out;
290 }
291 global.tune.maxrewrite = atol(args[1]);
292 if (global.tune.maxrewrite < 0) {
293 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
294 err_code |= ERR_ALERT | ERR_FATAL;
295 goto out;
296 }
297 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100298 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100299 unsigned int idle;
300 const char *res;
301
302 if (alertif_too_many_args(1, file, linenum, args, &err_code))
303 goto out;
304 if (*(args[1]) == 0) {
305 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
306 err_code |= ERR_ALERT | ERR_FATAL;
307 goto out;
308 }
309
310 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200311 if (res == PARSE_TIME_OVER) {
312 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
313 file, linenum, args[1], args[0]);
314 err_code |= ERR_ALERT | ERR_FATAL;
315 goto out;
316 }
317 else if (res == PARSE_TIME_UNDER) {
318 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
319 file, linenum, args[1], args[0]);
320 err_code |= ERR_ALERT | ERR_FATAL;
321 goto out;
322 }
323 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100324 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200325 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100326 err_code |= ERR_ALERT | ERR_FATAL;
327 goto out;
328 }
329
330 if (idle > 65535) {
331 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
332 err_code |= ERR_ALERT | ERR_FATAL;
333 goto out;
334 }
335 global.tune.idle_timer = idle;
336 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100337 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100338 if (alertif_too_many_args(1, file, linenum, args, &err_code))
339 goto out;
340 if (global.tune.client_rcvbuf != 0) {
341 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
342 err_code |= ERR_ALERT;
343 goto out;
344 }
345 if (*(args[1]) == 0) {
346 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
347 err_code |= ERR_ALERT | ERR_FATAL;
348 goto out;
349 }
350 global.tune.client_rcvbuf = atol(args[1]);
351 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100352 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100353 if (alertif_too_many_args(1, file, linenum, args, &err_code))
354 goto out;
355 if (global.tune.server_rcvbuf != 0) {
356 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
357 err_code |= ERR_ALERT;
358 goto out;
359 }
360 if (*(args[1]) == 0) {
361 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
362 err_code |= ERR_ALERT | ERR_FATAL;
363 goto out;
364 }
365 global.tune.server_rcvbuf = atol(args[1]);
366 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100367 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100368 if (alertif_too_many_args(1, file, linenum, args, &err_code))
369 goto out;
370 if (global.tune.client_sndbuf != 0) {
371 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
372 err_code |= ERR_ALERT;
373 goto out;
374 }
375 if (*(args[1]) == 0) {
376 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
377 err_code |= ERR_ALERT | ERR_FATAL;
378 goto out;
379 }
380 global.tune.client_sndbuf = atol(args[1]);
381 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100382 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100383 if (alertif_too_many_args(1, file, linenum, args, &err_code))
384 goto out;
385 if (global.tune.server_sndbuf != 0) {
386 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
387 err_code |= ERR_ALERT;
388 goto out;
389 }
390 if (*(args[1]) == 0) {
391 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
392 err_code |= ERR_ALERT | ERR_FATAL;
393 goto out;
394 }
395 global.tune.server_sndbuf = atol(args[1]);
396 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100397 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100398 if (alertif_too_many_args(1, file, linenum, args, &err_code))
399 goto out;
400 if (*(args[1]) == 0) {
401 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
402 err_code |= ERR_ALERT | ERR_FATAL;
403 goto out;
404 }
405 global.tune.pipesize = atol(args[1]);
406 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100407 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100408 if (alertif_too_many_args(1, file, linenum, args, &err_code))
409 goto out;
410 if (*(args[1]) == 0) {
411 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
412 err_code |= ERR_ALERT | ERR_FATAL;
413 goto out;
414 }
415 global.tune.cookie_len = atol(args[1]) + 1;
416 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100417 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100418 if (alertif_too_many_args(1, file, linenum, args, &err_code))
419 goto out;
420 if (*(args[1]) == 0) {
421 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
422 err_code |= ERR_ALERT | ERR_FATAL;
423 goto out;
424 }
425 global.tune.requri_len = atol(args[1]) + 1;
426 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100427 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100428 if (alertif_too_many_args(1, file, linenum, args, &err_code))
429 goto out;
430 if (*(args[1]) == 0) {
431 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
432 err_code |= ERR_ALERT | ERR_FATAL;
433 goto out;
434 }
435 global.tune.max_http_hdr = atoi(args[1]);
436 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
437 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
438 file, linenum, args[0]);
439 err_code |= ERR_ALERT | ERR_FATAL;
440 goto out;
441 }
442 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100443 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100444 if (alertif_too_many_args(1, file, linenum, args, &err_code))
445 goto out;
446 if (*args[1]) {
447 global.tune.comp_maxlevel = atoi(args[1]);
448 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
449 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
450 file, linenum, args[0]);
451 err_code |= ERR_ALERT | ERR_FATAL;
452 goto out;
453 }
454 } else {
455 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
456 file, linenum, args[0]);
457 err_code |= ERR_ALERT | ERR_FATAL;
458 goto out;
459 }
460 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100461 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100462 if (*args[1]) {
463 global.tune.pattern_cache = atoi(args[1]);
464 if (global.tune.pattern_cache < 0) {
465 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
466 file, linenum, args[0]);
467 err_code |= ERR_ALERT | ERR_FATAL;
468 goto out;
469 }
470 } else {
471 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
472 file, linenum, args[0]);
473 err_code |= ERR_ALERT | ERR_FATAL;
474 goto out;
475 }
476 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100477 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100478 if (alertif_too_many_args(1, file, linenum, args, &err_code))
479 goto out;
480 if (global.uid != 0) {
481 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
482 err_code |= ERR_ALERT;
483 goto out;
484 }
485 if (*(args[1]) == 0) {
486 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
487 err_code |= ERR_ALERT | ERR_FATAL;
488 goto out;
489 }
490 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
491 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
492 err_code |= ERR_WARN;
493 goto out;
494 }
495
496 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100497 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100498 if (alertif_too_many_args(1, file, linenum, args, &err_code))
499 goto out;
500 if (global.gid != 0) {
501 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
502 err_code |= ERR_ALERT;
503 goto out;
504 }
505 if (*(args[1]) == 0) {
506 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
507 err_code |= ERR_ALERT | ERR_FATAL;
508 goto out;
509 }
510 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
511 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
512 err_code |= ERR_WARN;
513 goto out;
514 }
515 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100516 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100517 if (alertif_too_many_args(0, file, linenum, args, &err_code))
518 goto out;
519 global.external_check = 1;
520 }
521 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100522 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100523 struct passwd *ha_user;
524 if (alertif_too_many_args(1, file, linenum, args, &err_code))
525 goto out;
526 if (global.uid != 0) {
527 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
528 err_code |= ERR_ALERT;
529 goto out;
530 }
531 errno = 0;
532 ha_user = getpwnam(args[1]);
533 if (ha_user != NULL) {
534 global.uid = (int)ha_user->pw_uid;
535 }
536 else {
537 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
538 err_code |= ERR_ALERT | ERR_FATAL;
539 }
540 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100541 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100542 struct group *ha_group;
543 if (alertif_too_many_args(1, file, linenum, args, &err_code))
544 goto out;
545 if (global.gid != 0) {
546 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
547 err_code |= ERR_ALERT;
548 goto out;
549 }
550 errno = 0;
551 ha_group = getgrnam(args[1]);
552 if (ha_group != NULL) {
553 global.gid = (int)ha_group->gr_gid;
554 }
555 else {
556 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
557 err_code |= ERR_ALERT | ERR_FATAL;
558 }
559 }
560 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100561 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100562 if (alertif_too_many_args(1, file, linenum, args, &err_code))
563 goto out;
564 if (*(args[1]) == 0) {
565 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
566 err_code |= ERR_ALERT | ERR_FATAL;
567 goto out;
568 }
569 global.nbproc = atol(args[1]);
Willy Tarreaua38a7172019-02-02 17:11:28 +0100570 all_proc_mask = nbits(global.nbproc);
Willy Tarreauff9c9142019-02-07 10:39:36 +0100571 if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100572 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
Willy Tarreauff9c9142019-02-07 10:39:36 +0100573 file, linenum, args[0], MAX_PROCS, global.nbproc);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100574 err_code |= ERR_ALERT | ERR_FATAL;
575 goto out;
576 }
577 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100578 else if (strcmp(args[0], "nbthread") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100579 if (alertif_too_many_args(1, file, linenum, args, &err_code))
580 goto out;
581 if (*(args[1]) == 0) {
582 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
583 err_code |= ERR_ALERT | ERR_FATAL;
584 goto out;
585 }
Amaury Denoyellec4d47d62021-03-29 10:41:15 +0200586
587 HA_DIAG_WARNING_COND(global.nbthread,
588 "parsing [%s:%d] : nbthread is already defined and will be overridden.\n",
589 file, linenum);
590
Willy Tarreau36b9e222018-11-11 15:19:52 +0100591 global.nbthread = parse_nbthread(args[1], &errmsg);
592 if (!global.nbthread) {
593 ha_alert("parsing [%s:%d] : '%s' %s.\n",
594 file, linenum, args[0], errmsg);
595 err_code |= ERR_ALERT | ERR_FATAL;
596 goto out;
597 }
598 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100599 else if (strcmp(args[0], "maxconn") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100600 if (alertif_too_many_args(1, file, linenum, args, &err_code))
601 goto out;
602 if (global.maxconn != 0) {
603 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
604 err_code |= ERR_ALERT;
605 goto out;
606 }
607 if (*(args[1]) == 0) {
608 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
609 err_code |= ERR_ALERT | ERR_FATAL;
610 goto out;
611 }
612 global.maxconn = atol(args[1]);
613#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100614 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
615 ha_alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, SYSTEM_MAXCONN);
616 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100617 err_code |= ERR_ALERT;
618 }
619#endif /* SYSTEM_MAXCONN */
620 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100621 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100622 if (alertif_too_many_args(1, file, linenum, args, &err_code))
623 goto out;
624 if (*(args[1]) == 0) {
625 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
626 err_code |= ERR_ALERT | ERR_FATAL;
627 goto out;
628 }
629 if (strcmp(args[1],"none") == 0)
630 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
631 else if (strcmp(args[1],"required") == 0)
632 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
633 else {
634 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
635 err_code |= ERR_ALERT | ERR_FATAL;
636 goto out;
637 }
638 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100639 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100640 if (alertif_too_many_args(1, file, linenum, args, &err_code))
641 goto out;
642 if (global.cps_lim != 0) {
643 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
644 err_code |= ERR_ALERT;
645 goto out;
646 }
647 if (*(args[1]) == 0) {
648 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
649 err_code |= ERR_ALERT | ERR_FATAL;
650 goto out;
651 }
652 global.cps_lim = atol(args[1]);
653 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100654 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100655 if (alertif_too_many_args(1, file, linenum, args, &err_code))
656 goto out;
657 if (global.sps_lim != 0) {
658 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
659 err_code |= ERR_ALERT;
660 goto out;
661 }
662 if (*(args[1]) == 0) {
663 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
664 err_code |= ERR_ALERT | ERR_FATAL;
665 goto out;
666 }
667 global.sps_lim = atol(args[1]);
668 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100669 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100670 if (alertif_too_many_args(1, file, linenum, args, &err_code))
671 goto out;
672 if (global.ssl_lim != 0) {
673 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
674 err_code |= ERR_ALERT;
675 goto out;
676 }
677 if (*(args[1]) == 0) {
678 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
679 err_code |= ERR_ALERT | ERR_FATAL;
680 goto out;
681 }
682 global.ssl_lim = atol(args[1]);
683 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100684 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100685 if (alertif_too_many_args(1, file, linenum, args, &err_code))
686 goto out;
687 if (*(args[1]) == 0) {
688 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
689 err_code |= ERR_ALERT | ERR_FATAL;
690 goto out;
691 }
692 global.comp_rate_lim = atoi(args[1]) * 1024;
693 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100694 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100695 if (alertif_too_many_args(1, file, linenum, args, &err_code))
696 goto out;
697 if (global.maxpipes != 0) {
698 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
699 err_code |= ERR_ALERT;
700 goto out;
701 }
702 if (*(args[1]) == 0) {
703 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
704 err_code |= ERR_ALERT | ERR_FATAL;
705 goto out;
706 }
707 global.maxpipes = atol(args[1]);
708 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100709 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100710 if (alertif_too_many_args(1, file, linenum, args, &err_code))
711 goto out;
712 if (*(args[1]) == 0) {
713 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
714 err_code |= ERR_ALERT | ERR_FATAL;
715 goto out;
716 }
717 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
718 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100719 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100720 if (alertif_too_many_args(1, file, linenum, args, &err_code))
721 goto out;
722 if (*(args[1]) == 0) {
723 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
724 err_code |= ERR_ALERT | ERR_FATAL;
725 goto out;
726 }
727 compress_min_idle = 100 - atoi(args[1]);
728 if (compress_min_idle > 100) {
729 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
730 err_code |= ERR_ALERT | ERR_FATAL;
731 goto out;
732 }
733 }
734
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100735 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100736 if (alertif_too_many_args(1, file, linenum, args, &err_code))
737 goto out;
738 if (global.rlimit_nofile != 0) {
739 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
740 err_code |= ERR_ALERT;
741 goto out;
742 }
743 if (*(args[1]) == 0) {
744 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
745 err_code |= ERR_ALERT | ERR_FATAL;
746 goto out;
747 }
748 global.rlimit_nofile = atol(args[1]);
749 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100750 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100751 if (alertif_too_many_args(1, file, linenum, args, &err_code))
752 goto out;
753 if (global.chroot != NULL) {
754 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
755 err_code |= ERR_ALERT;
756 goto out;
757 }
758 if (*(args[1]) == 0) {
759 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
760 err_code |= ERR_ALERT | ERR_FATAL;
761 goto out;
762 }
763 global.chroot = strdup(args[1]);
764 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100765 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100766 int i, len=0;
767 char *d;
768
769 if (!*args[1]) {
770 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
771 file, linenum, args[0]);
772 err_code |= ERR_ALERT | ERR_FATAL;
773 goto out;
774 }
775
776 for (i = 1; *args[i]; i++)
777 len += strlen(args[i]) + 1;
778
779 if (global.desc)
780 free(global.desc);
781
782 global.desc = d = calloc(1, len);
783
784 d += snprintf(d, global.desc + len - d, "%s", args[1]);
785 for (i = 2; *args[i]; i++)
786 d += snprintf(d, global.desc + len - d, " %s", args[i]);
787 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100788 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100789 int i;
790 char c;
791
792 if (alertif_too_many_args(1, file, linenum, args, &err_code))
793 goto out;
794
795 for (i=0; args[1][i]; i++) {
796 c = args[1][i];
797 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
798 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
799 break;
800 }
801
802 if (!i || args[1][i]) {
803 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
804 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
805 file, linenum, args[0]);
806 err_code |= ERR_ALERT | ERR_FATAL;
807 goto out;
808 }
809
810 if (global.node)
811 free(global.node);
812
813 global.node = strdup(args[1]);
814 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100815 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100816 if (alertif_too_many_args(1, file, linenum, args, &err_code))
817 goto out;
818 if (global.pidfile != NULL) {
819 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
820 err_code |= ERR_ALERT;
821 goto out;
822 }
823 if (*(args[1]) == 0) {
824 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
825 err_code |= ERR_ALERT | ERR_FATAL;
826 goto out;
827 }
828 global.pidfile = strdup(args[1]);
829 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100830 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100831 int cur_arg = 1;
832 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100833 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100834 if (global.unix_bind.prefix != NULL) {
835 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
836 err_code |= ERR_ALERT;
837 cur_arg += 2;
838 continue;
839 }
840
841 if (*(args[cur_arg+1]) == 0) {
842 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
843 err_code |= ERR_ALERT | ERR_FATAL;
844 goto out;
845 }
846 global.unix_bind.prefix = strdup(args[cur_arg+1]);
847 cur_arg += 2;
848 continue;
849 }
850
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100851 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100852
853 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
854 cur_arg += 2;
855 continue;
856 }
857
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100858 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100859
860 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
861 cur_arg += 2;
862 continue;
863 }
864
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100865 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100866
867 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
868 cur_arg += 2;
869 continue;
870 }
871
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100872 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100873 struct passwd *user;
874
875 user = getpwnam(args[cur_arg + 1]);
876 if (!user) {
877 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
878 file, linenum, args[0], args[cur_arg + 1 ]);
879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882
883 global.unix_bind.ux.uid = user->pw_uid;
884 cur_arg += 2;
885 continue;
886 }
887
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100888 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100889 struct group *group;
890
891 group = getgrnam(args[cur_arg + 1]);
892 if (!group) {
893 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
894 file, linenum, args[0], args[cur_arg + 1 ]);
895 err_code |= ERR_ALERT | ERR_FATAL;
896 goto out;
897 }
898
899 global.unix_bind.ux.gid = group->gr_gid;
900 cur_arg += 2;
901 continue;
902 }
903
904 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
905 file, linenum, args[0]);
906 err_code |= ERR_ALERT | ERR_FATAL;
907 goto out;
908 }
909 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100910 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200911 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100912 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
913 err_code |= ERR_ALERT | ERR_FATAL;
914 goto out;
915 }
916 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100917 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100918 char *name;
919
920 if (global.log_send_hostname != NULL) {
921 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
922 err_code |= ERR_ALERT;
923 goto out;
924 }
925
926 if (*(args[1]))
927 name = args[1];
928 else
929 name = hostname;
930
931 free(global.log_send_hostname);
932 global.log_send_hostname = strdup(name);
933 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100934 else if (strcmp(args[0], "server-state-base") == 0) { /* path base where HAProxy can find server state files */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100935 if (global.server_state_base != NULL) {
936 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
937 err_code |= ERR_ALERT;
938 goto out;
939 }
940
941 if (!*(args[1])) {
942 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
943 err_code |= ERR_FATAL;
944 goto out;
945 }
946
947 global.server_state_base = strdup(args[1]);
948 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100949 else if (strcmp(args[0], "server-state-file") == 0) { /* path to the file where HAProxy can load the server states */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100950 if (global.server_state_file != NULL) {
951 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
952 err_code |= ERR_ALERT;
953 goto out;
954 }
955
956 if (!*(args[1])) {
957 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
958 err_code |= ERR_FATAL;
959 goto out;
960 }
961
962 global.server_state_file = strdup(args[1]);
963 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100964 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100965 if (alertif_too_many_args(1, file, linenum, args, &err_code))
966 goto out;
967 if (*(args[1]) == 0) {
968 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
969 err_code |= ERR_ALERT | ERR_FATAL;
970 goto out;
971 }
972 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +0200973 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
974 if (b_orig(&global.log_tag) == NULL) {
975 chunk_destroy(&global.log_tag);
976 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
977 err_code |= ERR_ALERT | ERR_FATAL;
978 goto out;
979 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100980 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100981 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100982 if (alertif_too_many_args(1, file, linenum, args, &err_code))
983 goto out;
984 if (global.spread_checks != 0) {
985 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
986 err_code |= ERR_ALERT;
987 goto out;
988 }
989 if (*(args[1]) == 0) {
990 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
991 err_code |= ERR_ALERT | ERR_FATAL;
992 goto out;
993 }
994 global.spread_checks = atol(args[1]);
995 if (global.spread_checks < 0 || global.spread_checks > 50) {
996 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
997 err_code |= ERR_ALERT | ERR_FATAL;
998 }
999 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001000 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001001 const char *err;
1002 unsigned int val;
1003
1004 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1005 goto out;
1006 if (*(args[1]) == 0) {
1007 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1008 err_code |= ERR_ALERT | ERR_FATAL;
1009 goto out;
1010 }
1011
1012 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001013 if (err == PARSE_TIME_OVER) {
1014 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1015 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001016 err_code |= ERR_ALERT | ERR_FATAL;
1017 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001018 else if (err == PARSE_TIME_UNDER) {
1019 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1020 file, linenum, args[1], args[0]);
1021 err_code |= ERR_ALERT | ERR_FATAL;
1022 }
1023 else if (err) {
1024 ha_alert("parsing [%s:%d]: unsupported character '%c' in '%s' (wants an integer delay).\n", file, linenum, *err, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001025 err_code |= ERR_ALERT | ERR_FATAL;
1026 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001027 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001028 }
1029 else if (strcmp(args[0], "cpu-map") == 0) {
1030 /* map a process list to a CPU set */
1031#ifdef USE_CPU_AFFINITY
1032 char *slash;
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001033 unsigned long proc = 0, thread = 0;
1034 int i, j, n, autoinc;
1035 struct hap_cpuset cpus, cpus_copy;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001036
1037 if (!*args[1] || !*args[2]) {
1038 ha_alert("parsing [%s:%d] : %s expects a process number "
1039 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1040 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001041 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001042 err_code |= ERR_ALERT | ERR_FATAL;
1043 goto out;
1044 }
1045
1046 if ((slash = strchr(args[1], '/')) != NULL)
1047 *slash = 0;
1048
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001049 /* note: we silently ignore processes over MAX_PROCS and
1050 * threads over MAX_THREADS so as not to make configurations a
1051 * pain to maintain.
1052 */
1053 if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001054 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1055 err_code |= ERR_ALERT | ERR_FATAL;
1056 goto out;
1057 }
1058
1059 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001060 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001061 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1062 err_code |= ERR_ALERT | ERR_FATAL;
1063 goto out;
1064 }
1065 *slash = '/';
1066
1067 if (autoinc && atleast2(proc) && atleast2(thread)) {
1068 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1069 "a process range _AND_ a thread range\n",
1070 file, linenum, args[0], args[1]);
1071 err_code |= ERR_ALERT | ERR_FATAL;
1072 goto out;
1073 }
1074 }
1075
Amaury Denoyellea8082352021-04-06 16:46:15 +02001076 if (parse_cpu_set((const char **)args+2, &cpus, 0, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001077 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1078 err_code |= ERR_ALERT | ERR_FATAL;
1079 goto out;
1080 }
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001081
Willy Tarreau36b9e222018-11-11 15:19:52 +01001082 if (autoinc &&
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001083 my_popcountl(proc) != ha_cpuset_count(&cpus) &&
1084 my_popcountl(thread) != ha_cpuset_count(&cpus)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001085 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1086 "must have the same size to be automatically bound\n",
1087 file, linenum, args[0]);
1088 err_code |= ERR_ALERT | ERR_FATAL;
1089 goto out;
1090 }
1091
Willy Tarreau7764a572019-07-16 15:10:34 +02001092 /* we now have to deal with 3 real cases :
1093 * cpu-map P-Q => mapping for whole processes, numbers P to Q
1094 * cpu-map P-Q/1 => mapping of first thread of processes P to Q
1095 * cpu-map 1/T-U => mapping of threads T to U of process 1
1096 * Otherwise other combinations are silently ignored since nbthread
1097 * and nbproc cannot both be >1 :
1098 * cpu-map P-Q/T => mapping for thread T for processes P to Q.
1099 * Only one of T,Q may be > 1, others ignored.
1100 * cpu-map P/T-U => mapping for threads T to U of process P. Only
1101 * one of P,U may be > 1, others ignored.
1102 */
1103 if (!thread) {
1104 /* mapping for whole processes. E.g. cpu-map 1-4 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001105 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau81492c92019-05-03 09:41:23 +02001106 for (i = n = 0; i < MAX_PROCS; i++) {
1107 /* No mapping for this process */
1108 if (!(proc & (1UL << i)))
1109 continue;
1110
Willy Tarreau36b9e222018-11-11 15:19:52 +01001111 if (!autoinc)
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001112 ha_cpuset_assign(&global.cpu_map.proc[i], &cpus);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001113 else {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001114 ha_cpuset_zero(&global.cpu_map.proc[i]);
1115 n = ha_cpuset_ffs(&cpus_copy) - 1;
1116 ha_cpuset_clr(&cpus_copy, n);
1117 ha_cpuset_set(&global.cpu_map.proc[i], n);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001118 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001119 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001120 } else {
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001121 /* Mapping at the thread level.
1122 * Either proc and/or thread must be 1 and only 1. All
1123 * other combinations are silently ignored.
Willy Tarreau7764a572019-07-16 15:10:34 +02001124 */
1125 if (thread == 0x1) {
1126 /* first thread, iterate on processes. E.g. cpu-map 1-4/1 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001127 struct hap_cpuset *dst;
1128
1129 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001130 for (i = n = 0; i < MAX_PROCS; i++) {
1131 /* No mapping for this process */
1132 if (!(proc & (1UL << i)))
1133 continue;
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001134
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001135 /* For first process, thread[0] is used.
1136 * Use proc_t1[N] for all others
1137 */
1138 dst = i ? &global.cpu_map.proc_t1[i] :
1139 &global.cpu_map.thread[0];
1140
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001141 if (!autoinc) {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001142 ha_cpuset_assign(dst, &cpus);
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001143 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001144 else {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001145 ha_cpuset_zero(dst);
1146 n = ha_cpuset_ffs(&cpus_copy) - 1;
1147 ha_cpuset_clr(&cpus_copy, n);
1148 ha_cpuset_set(dst, n);
Willy Tarreau7764a572019-07-16 15:10:34 +02001149 }
1150 }
1151 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001152
Willy Tarreau7764a572019-07-16 15:10:34 +02001153 if (proc == 0x1) {
1154 /* first process, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001155 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001156 for (j = n = 0; j < MAX_THREADS; j++) {
1157 /* No mapping for this thread */
1158 if (!(thread & (1UL << j)))
1159 continue;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001160
Willy Tarreau7764a572019-07-16 15:10:34 +02001161 if (!autoinc)
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001162 ha_cpuset_assign(&global.cpu_map.thread[j], &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001163 else {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001164 ha_cpuset_zero(&global.cpu_map.thread[j]);
1165 n = ha_cpuset_ffs(&cpus_copy) - 1;
1166 ha_cpuset_clr(&cpus_copy, n);
1167 ha_cpuset_set(&global.cpu_map.thread[j], n);
Willy Tarreau7764a572019-07-16 15:10:34 +02001168 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001169 }
1170 }
Amaury Denoyellea2944ec2021-04-15 18:07:07 +02001171
1172 HA_DIAG_WARNING_COND(proc != 0x1 && thread != 0x1,
1173 "parsing [%s:%d] : cpu-map statement is considered invalid and thus ignored as it addresses multiple processes and threads at the same time. At least one of them should be 1 and only 1.", file, linenum);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001174 }
1175#else
1176 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1177 file, linenum, args[0]);
1178 err_code |= ERR_ALERT | ERR_FATAL;
1179 goto out;
1180#endif /* ! USE_CPU_AFFINITY */
1181 }
1182 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1183 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1184 goto out;
1185
1186 if (*(args[2]) == 0) {
1187 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1188 err_code |= ERR_ALERT | ERR_FATAL;
1189 goto out;
1190 }
1191
1192 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1193 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1194 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1195 err_code |= ERR_ALERT | ERR_FATAL;
1196 goto out;
1197 }
1198 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001199 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001200 int arg;
1201
1202 if (*(args[1]) == 0) {
1203 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1204 err_code |= ERR_ALERT | ERR_FATAL;
1205 goto out;
1206 }
1207
1208 for (arg = 1; *args[arg]; arg++) {
1209 if (unsetenv(args[arg]) != 0) {
1210 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1211 err_code |= ERR_ALERT | ERR_FATAL;
1212 goto out;
1213 }
1214 }
1215 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001216 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001217 extern char **environ;
1218 char **env = environ;
1219
1220 /* args contain variable names to keep, one per argument */
1221 while (*env) {
1222 int arg;
1223
1224 /* look for current variable in among all those we want to keep */
1225 for (arg = 1; *args[arg]; arg++) {
1226 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1227 (*env)[strlen(args[arg])] == '=')
1228 break;
1229 }
1230
1231 /* delete this variable */
1232 if (!*args[arg]) {
1233 char *delim = strchr(*env, '=');
1234
1235 if (!delim || delim - *env >= trash.size) {
1236 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1237 err_code |= ERR_ALERT | ERR_FATAL;
1238 goto out;
1239 }
1240
1241 memcpy(trash.area, *env, delim - *env);
1242 trash.area[delim - *env] = 0;
1243
1244 if (unsetenv(trash.area) != 0) {
1245 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1246 err_code |= ERR_ALERT | ERR_FATAL;
1247 goto out;
1248 }
1249 }
1250 else
1251 env++;
1252 }
1253 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001254 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001255 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1256 goto out;
1257 if (kwm == KWM_NO)
1258 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001259 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001260 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001261 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1262 goto out;
1263
1264 if (*(args[1]) == 0) {
1265 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1266 file, linenum, args[0]);
1267 err_code |= ERR_ALERT | ERR_FATAL;
1268 goto out;
1269 }
1270
1271 if (global.localpeer_cmdline != 0) {
1272 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1273 "command line argument.\n", file, linenum, args[0]);
1274 err_code |= ERR_WARN;
1275 goto out;
1276 }
1277
1278 if (cfg_peers) {
1279 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1280 file, linenum, args[0]);
1281 err_code |= ERR_WARN;
1282 goto out;
1283 }
1284
1285 free(localpeer);
1286 if ((localpeer = strdup(args[1])) == NULL) {
1287 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1288 file, linenum, args[0]);
1289 err_code |= ERR_ALERT | ERR_FATAL;
1290 goto out;
1291 }
1292 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1293 }
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +01001294 else if (strcmp(args[0], "numa-cpu-mapping") == 0) {
1295 global.numa_cpu_mapping = (kwm == KWM_NO) ? 0 : 1;
1296 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001297 else {
1298 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001299 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001300 int index;
1301 int rc;
1302
1303 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1304 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1305 if (kwl->kw[index].section != CFG_GLOBAL)
1306 continue;
1307 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
1308 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1309 if (rc < 0) {
1310 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1311 err_code |= ERR_ALERT | ERR_FATAL;
1312 }
1313 else if (rc > 0) {
1314 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1315 err_code |= ERR_WARN;
1316 goto out;
1317 }
1318 goto out;
1319 }
1320 }
1321 }
1322
Willy Tarreau101df312021-03-15 09:12:41 +01001323 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001324 if (best)
1325 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1326 else
1327 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001328 err_code |= ERR_ALERT | ERR_FATAL;
1329 }
1330
1331 out:
1332 free(errmsg);
1333 return err_code;
1334}
1335