blob: 40f3018b3e21c1fa880f9d1d77f0f3d353097b72 [file] [log] [blame]
Amaury Denoyellec90932b2021-04-14 16:16:03 +02001#define _GNU_SOURCE /* for CPU_* from cpuset.h */
Willy Tarreau36b9e222018-11-11 15:19:52 +01002#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <netdb.h>
6#include <ctype.h>
7#include <pwd.h>
8#include <grp.h>
9#include <errno.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <unistd.h>
14
Eric Salama7cea6062020-10-02 11:58:19 +020015#include <haproxy/buf.h>
Willy Tarreau6be78492020-06-05 00:00:29 +020016#include <haproxy/cfgparse.h>
Amaury Denoyellec90932b2021-04-14 16:16:03 +020017#include <haproxy/cpuset.h>
Willy Tarreau0a3bd392020-06-04 08:52:38 +020018#include <haproxy/compression.h>
Willy Tarreaudfd3de82020-06-04 23:46:14 +020019#include <haproxy/global.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020020#include <haproxy/log.h>
Dragan Dosen13cd54c2020-06-18 18:24:05 +020021#include <haproxy/peers.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020022#include <haproxy/tools.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010023
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010024/* some keywords that are still being parsed using strcmp() and are not
25 * registered anywhere. They are used as suggestions for mistyped words.
26 */
27static const char *common_kw_list[] = {
28 "global", "daemon", "master-worker", "noepoll", "nokqueue",
29 "noevports", "nopoll", "busy-polling", "set-dumpable",
30 "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
31 "nogetaddrinfo", "noreuseport", "quiet", "zero-warning",
32 "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept",
33 "tune.chksize", "tune.recv_enough", "tune.buffers.limit",
34 "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite",
35 "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server",
36 "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize",
37 "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr",
38 "tune.comp.maxlevel", "tune.pattern.cache-size", "uid", "gid",
39 "external-check", "user", "group", "nbproc", "nbthread", "maxconn",
40 "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
41 "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n",
42 "chroot", "description", "node", "pidfile", "unix-bind", "log",
43 "log-send-hostname", "server-state-base", "server-state-file",
44 "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv",
45 "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer",
46 "defaults", "listen", "frontend", "backend", "peers", "resolvers",
47 NULL /* must be last */
48};
49
Willy Tarreau36b9e222018-11-11 15:19:52 +010050/*
51 * parse a line in a <global> section. Returns the error code, 0 if OK, or
52 * any combination of :
53 * - ERR_ABORT: must abort ASAP
54 * - ERR_FATAL: we can continue parsing but not start the service
55 * - ERR_WARN: a warning has been emitted
56 * - ERR_ALERT: an alert has been emitted
57 * Only the two first ones can stop processing, the two others are just
58 * indicators.
59 */
60int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
61{
62 int err_code = 0;
63 char *errmsg = NULL;
64
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010065 if (strcmp(args[0], "global") == 0) { /* new section */
Willy Tarreau36b9e222018-11-11 15:19:52 +010066 /* no option, nothing special to do */
67 alertif_too_many_args(0, file, linenum, args, &err_code);
68 goto out;
69 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010070 else if (strcmp(args[0], "daemon") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010071 if (alertif_too_many_args(0, file, linenum, args, &err_code))
72 goto out;
73 global.mode |= MODE_DAEMON;
74 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010075 else if (strcmp(args[0], "master-worker") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010076 if (alertif_too_many_args(1, file, linenum, args, &err_code))
77 goto out;
78 if (*args[1]) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010079 if (strcmp(args[1], "no-exit-on-failure") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010080 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
81 } else {
82 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
83 err_code |= ERR_ALERT | ERR_FATAL;
84 goto out;
85 }
86 }
87 global.mode |= MODE_MWORKER;
88 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010089 else if (strcmp(args[0], "noepoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010090 if (alertif_too_many_args(0, file, linenum, args, &err_code))
91 goto out;
92 global.tune.options &= ~GTUNE_USE_EPOLL;
93 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010094 else if (strcmp(args[0], "nokqueue") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010095 if (alertif_too_many_args(0, file, linenum, args, &err_code))
96 goto out;
97 global.tune.options &= ~GTUNE_USE_KQUEUE;
98 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010099 else if (strcmp(args[0], "noevports") == 0) {
Emmanuel Hocdet0ba4f482019-04-08 16:53:32 +0000100 if (alertif_too_many_args(0, file, linenum, args, &err_code))
101 goto out;
102 global.tune.options &= ~GTUNE_USE_EVPORTS;
103 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100104 else if (strcmp(args[0], "nopoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100105 if (alertif_too_many_args(0, file, linenum, args, &err_code))
106 goto out;
107 global.tune.options &= ~GTUNE_USE_POLL;
108 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100109 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100110 if (alertif_too_many_args(0, file, linenum, args, &err_code))
111 goto out;
112 if (kwm == KWM_NO)
113 global.tune.options &= ~GTUNE_BUSY_POLLING;
114 else
115 global.tune.options |= GTUNE_BUSY_POLLING;
116 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100117 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200118 if (alertif_too_many_args(0, file, linenum, args, &err_code))
119 goto out;
120 if (kwm == KWM_NO)
121 global.tune.options &= ~GTUNE_SET_DUMPABLE;
122 else
123 global.tune.options |= GTUNE_SET_DUMPABLE;
124 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100125 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100126 if (alertif_too_many_args(0, file, linenum, args, &err_code))
127 goto out;
128 if (kwm == KWM_NO)
129 global.tune.options &= ~GTUNE_INSECURE_FORK;
130 else
131 global.tune.options |= GTUNE_INSECURE_FORK;
132 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100133 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100134 if (alertif_too_many_args(0, file, linenum, args, &err_code))
135 goto out;
136 if (kwm == KWM_NO)
137 global.tune.options &= ~GTUNE_INSECURE_SETUID;
138 else
139 global.tune.options |= GTUNE_INSECURE_SETUID;
140 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100141 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100142 if (alertif_too_many_args(0, file, linenum, args, &err_code))
143 goto out;
144 global.tune.options &= ~GTUNE_USE_SPLICE;
145 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100146 else if (strcmp(args[0], "nogetaddrinfo") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100147 if (alertif_too_many_args(0, file, linenum, args, &err_code))
148 goto out;
149 global.tune.options &= ~GTUNE_USE_GAI;
150 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100151 else if (strcmp(args[0], "noreuseport") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100152 if (alertif_too_many_args(0, file, linenum, args, &err_code))
153 goto out;
154 global.tune.options &= ~GTUNE_USE_REUSEPORT;
155 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100156 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100157 if (alertif_too_many_args(0, file, linenum, args, &err_code))
158 goto out;
159 global.mode |= MODE_QUIET;
160 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100161 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200162 if (alertif_too_many_args(0, file, linenum, args, &err_code))
163 goto out;
164 global.mode |= MODE_ZERO_WARNING;
165 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100166 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100167 if (alertif_too_many_args(1, file, linenum, args, &err_code))
168 goto out;
169 if (global.tune.runqueue_depth != 0) {
170 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
171 err_code |= ERR_ALERT;
172 goto out;
173 }
174 if (*(args[1]) == 0) {
175 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
176 err_code |= ERR_ALERT | ERR_FATAL;
177 goto out;
178 }
179 global.tune.runqueue_depth = atol(args[1]);
180
181 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100182 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100183 if (alertif_too_many_args(1, file, linenum, args, &err_code))
184 goto out;
185 if (global.tune.maxpollevents != 0) {
186 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
187 err_code |= ERR_ALERT;
188 goto out;
189 }
190 if (*(args[1]) == 0) {
191 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
192 err_code |= ERR_ALERT | ERR_FATAL;
193 goto out;
194 }
195 global.tune.maxpollevents = atol(args[1]);
196 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100197 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200198 long max;
199
Willy Tarreau36b9e222018-11-11 15:19:52 +0100200 if (alertif_too_many_args(1, file, linenum, args, &err_code))
201 goto out;
202 if (global.tune.maxaccept != 0) {
203 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
204 err_code |= ERR_ALERT;
205 goto out;
206 }
207 if (*(args[1]) == 0) {
208 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
209 err_code |= ERR_ALERT | ERR_FATAL;
210 goto out;
211 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200212 max = atol(args[1]);
213 if (/*max < -1 || */max > INT_MAX) {
214 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
215 err_code |= ERR_ALERT | ERR_FATAL;
216 goto out;
217 }
218 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100219 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100220 else if (strcmp(args[0], "tune.chksize") == 0) {
Christopher Fauletf8c869b2020-11-25 17:33:03 +0100221 ha_warning("parsing [%s:%d]: the option '%s' is deprecated and will be removed in next version.\n",
222 file, linenum, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100223 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100224 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100225 if (alertif_too_many_args(1, file, linenum, args, &err_code))
226 goto out;
227 if (*(args[1]) == 0) {
228 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
229 err_code |= ERR_ALERT | ERR_FATAL;
230 goto out;
231 }
232 global.tune.recv_enough = atol(args[1]);
233 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100234 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100235 if (alertif_too_many_args(1, file, linenum, args, &err_code))
236 goto out;
237 if (*(args[1]) == 0) {
238 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
239 err_code |= ERR_ALERT | ERR_FATAL;
240 goto out;
241 }
242 global.tune.buf_limit = atol(args[1]);
243 if (global.tune.buf_limit) {
244 if (global.tune.buf_limit < 3)
245 global.tune.buf_limit = 3;
246 if (global.tune.buf_limit <= global.tune.reserved_bufs)
247 global.tune.buf_limit = global.tune.reserved_bufs + 1;
248 }
249 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100250 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100251 if (alertif_too_many_args(1, file, linenum, args, &err_code))
252 goto out;
253 if (*(args[1]) == 0) {
254 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
255 err_code |= ERR_ALERT | ERR_FATAL;
256 goto out;
257 }
258 global.tune.reserved_bufs = atol(args[1]);
259 if (global.tune.reserved_bufs < 2)
260 global.tune.reserved_bufs = 2;
261 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
262 global.tune.buf_limit = global.tune.reserved_bufs + 1;
263 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100264 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100265 if (alertif_too_many_args(1, file, linenum, args, &err_code))
266 goto out;
267 if (*(args[1]) == 0) {
268 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
269 err_code |= ERR_ALERT | ERR_FATAL;
270 goto out;
271 }
272 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100273 /* round it up to support a two-pointer alignment at the end */
274 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100275 if (global.tune.bufsize <= 0) {
276 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
277 err_code |= ERR_ALERT | ERR_FATAL;
278 goto out;
279 }
280 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100281 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100282 if (alertif_too_many_args(1, file, linenum, args, &err_code))
283 goto out;
284 if (*(args[1]) == 0) {
285 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
286 err_code |= ERR_ALERT | ERR_FATAL;
287 goto out;
288 }
289 global.tune.maxrewrite = atol(args[1]);
290 if (global.tune.maxrewrite < 0) {
291 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
292 err_code |= ERR_ALERT | ERR_FATAL;
293 goto out;
294 }
295 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100296 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100297 unsigned int idle;
298 const char *res;
299
300 if (alertif_too_many_args(1, file, linenum, args, &err_code))
301 goto out;
302 if (*(args[1]) == 0) {
303 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
304 err_code |= ERR_ALERT | ERR_FATAL;
305 goto out;
306 }
307
308 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200309 if (res == PARSE_TIME_OVER) {
310 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
311 file, linenum, args[1], args[0]);
312 err_code |= ERR_ALERT | ERR_FATAL;
313 goto out;
314 }
315 else if (res == PARSE_TIME_UNDER) {
316 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
317 file, linenum, args[1], args[0]);
318 err_code |= ERR_ALERT | ERR_FATAL;
319 goto out;
320 }
321 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100322 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200323 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100324 err_code |= ERR_ALERT | ERR_FATAL;
325 goto out;
326 }
327
328 if (idle > 65535) {
329 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
330 err_code |= ERR_ALERT | ERR_FATAL;
331 goto out;
332 }
333 global.tune.idle_timer = idle;
334 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100335 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100336 if (alertif_too_many_args(1, file, linenum, args, &err_code))
337 goto out;
338 if (global.tune.client_rcvbuf != 0) {
339 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
340 err_code |= ERR_ALERT;
341 goto out;
342 }
343 if (*(args[1]) == 0) {
344 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
345 err_code |= ERR_ALERT | ERR_FATAL;
346 goto out;
347 }
348 global.tune.client_rcvbuf = atol(args[1]);
349 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100350 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100351 if (alertif_too_many_args(1, file, linenum, args, &err_code))
352 goto out;
353 if (global.tune.server_rcvbuf != 0) {
354 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
355 err_code |= ERR_ALERT;
356 goto out;
357 }
358 if (*(args[1]) == 0) {
359 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
360 err_code |= ERR_ALERT | ERR_FATAL;
361 goto out;
362 }
363 global.tune.server_rcvbuf = atol(args[1]);
364 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100365 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100366 if (alertif_too_many_args(1, file, linenum, args, &err_code))
367 goto out;
368 if (global.tune.client_sndbuf != 0) {
369 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
370 err_code |= ERR_ALERT;
371 goto out;
372 }
373 if (*(args[1]) == 0) {
374 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
375 err_code |= ERR_ALERT | ERR_FATAL;
376 goto out;
377 }
378 global.tune.client_sndbuf = atol(args[1]);
379 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100380 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100381 if (alertif_too_many_args(1, file, linenum, args, &err_code))
382 goto out;
383 if (global.tune.server_sndbuf != 0) {
384 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
385 err_code |= ERR_ALERT;
386 goto out;
387 }
388 if (*(args[1]) == 0) {
389 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
390 err_code |= ERR_ALERT | ERR_FATAL;
391 goto out;
392 }
393 global.tune.server_sndbuf = atol(args[1]);
394 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100395 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100396 if (alertif_too_many_args(1, file, linenum, args, &err_code))
397 goto out;
398 if (*(args[1]) == 0) {
399 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
400 err_code |= ERR_ALERT | ERR_FATAL;
401 goto out;
402 }
403 global.tune.pipesize = atol(args[1]);
404 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100405 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100406 if (alertif_too_many_args(1, file, linenum, args, &err_code))
407 goto out;
408 if (*(args[1]) == 0) {
409 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
410 err_code |= ERR_ALERT | ERR_FATAL;
411 goto out;
412 }
413 global.tune.cookie_len = atol(args[1]) + 1;
414 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100415 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100416 if (alertif_too_many_args(1, file, linenum, args, &err_code))
417 goto out;
418 if (*(args[1]) == 0) {
419 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
420 err_code |= ERR_ALERT | ERR_FATAL;
421 goto out;
422 }
423 global.tune.requri_len = atol(args[1]) + 1;
424 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100425 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100426 if (alertif_too_many_args(1, file, linenum, args, &err_code))
427 goto out;
428 if (*(args[1]) == 0) {
429 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
430 err_code |= ERR_ALERT | ERR_FATAL;
431 goto out;
432 }
433 global.tune.max_http_hdr = atoi(args[1]);
434 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
435 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
436 file, linenum, args[0]);
437 err_code |= ERR_ALERT | ERR_FATAL;
438 goto out;
439 }
440 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100441 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100442 if (alertif_too_many_args(1, file, linenum, args, &err_code))
443 goto out;
444 if (*args[1]) {
445 global.tune.comp_maxlevel = atoi(args[1]);
446 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
447 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
448 file, linenum, args[0]);
449 err_code |= ERR_ALERT | ERR_FATAL;
450 goto out;
451 }
452 } else {
453 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
454 file, linenum, args[0]);
455 err_code |= ERR_ALERT | ERR_FATAL;
456 goto out;
457 }
458 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100459 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100460 if (*args[1]) {
461 global.tune.pattern_cache = atoi(args[1]);
462 if (global.tune.pattern_cache < 0) {
463 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
464 file, linenum, args[0]);
465 err_code |= ERR_ALERT | ERR_FATAL;
466 goto out;
467 }
468 } else {
469 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
470 file, linenum, args[0]);
471 err_code |= ERR_ALERT | ERR_FATAL;
472 goto out;
473 }
474 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100475 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100476 if (alertif_too_many_args(1, file, linenum, args, &err_code))
477 goto out;
478 if (global.uid != 0) {
479 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
480 err_code |= ERR_ALERT;
481 goto out;
482 }
483 if (*(args[1]) == 0) {
484 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
485 err_code |= ERR_ALERT | ERR_FATAL;
486 goto out;
487 }
488 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
489 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]);
490 err_code |= ERR_WARN;
491 goto out;
492 }
493
494 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100495 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100496 if (alertif_too_many_args(1, file, linenum, args, &err_code))
497 goto out;
498 if (global.gid != 0) {
499 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
500 err_code |= ERR_ALERT;
501 goto out;
502 }
503 if (*(args[1]) == 0) {
504 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
505 err_code |= ERR_ALERT | ERR_FATAL;
506 goto out;
507 }
508 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
509 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]);
510 err_code |= ERR_WARN;
511 goto out;
512 }
513 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100514 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100515 if (alertif_too_many_args(0, file, linenum, args, &err_code))
516 goto out;
517 global.external_check = 1;
518 }
519 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100520 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100521 struct passwd *ha_user;
522 if (alertif_too_many_args(1, file, linenum, args, &err_code))
523 goto out;
524 if (global.uid != 0) {
525 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
526 err_code |= ERR_ALERT;
527 goto out;
528 }
529 errno = 0;
530 ha_user = getpwnam(args[1]);
531 if (ha_user != NULL) {
532 global.uid = (int)ha_user->pw_uid;
533 }
534 else {
535 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
536 err_code |= ERR_ALERT | ERR_FATAL;
537 }
538 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100539 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100540 struct group *ha_group;
541 if (alertif_too_many_args(1, file, linenum, args, &err_code))
542 goto out;
543 if (global.gid != 0) {
544 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
545 err_code |= ERR_ALERT;
546 goto out;
547 }
548 errno = 0;
549 ha_group = getgrnam(args[1]);
550 if (ha_group != NULL) {
551 global.gid = (int)ha_group->gr_gid;
552 }
553 else {
554 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
555 err_code |= ERR_ALERT | ERR_FATAL;
556 }
557 }
558 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100559 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100560 if (alertif_too_many_args(1, file, linenum, args, &err_code))
561 goto out;
562 if (*(args[1]) == 0) {
563 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
564 err_code |= ERR_ALERT | ERR_FATAL;
565 goto out;
566 }
567 global.nbproc = atol(args[1]);
Willy Tarreaua38a7172019-02-02 17:11:28 +0100568 all_proc_mask = nbits(global.nbproc);
Willy Tarreauff9c9142019-02-07 10:39:36 +0100569 if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100570 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
Willy Tarreauff9c9142019-02-07 10:39:36 +0100571 file, linenum, args[0], MAX_PROCS, global.nbproc);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100572 err_code |= ERR_ALERT | ERR_FATAL;
573 goto out;
574 }
575 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100576 else if (strcmp(args[0], "nbthread") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100577 if (alertif_too_many_args(1, file, linenum, args, &err_code))
578 goto out;
579 if (*(args[1]) == 0) {
580 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
581 err_code |= ERR_ALERT | ERR_FATAL;
582 goto out;
583 }
Amaury Denoyellec4d47d62021-03-29 10:41:15 +0200584
585 HA_DIAG_WARNING_COND(global.nbthread,
586 "parsing [%s:%d] : nbthread is already defined and will be overridden.\n",
587 file, linenum);
588
Willy Tarreau36b9e222018-11-11 15:19:52 +0100589 global.nbthread = parse_nbthread(args[1], &errmsg);
590 if (!global.nbthread) {
591 ha_alert("parsing [%s:%d] : '%s' %s.\n",
592 file, linenum, args[0], errmsg);
593 err_code |= ERR_ALERT | ERR_FATAL;
594 goto out;
595 }
596 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100597 else if (strcmp(args[0], "maxconn") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100598 if (alertif_too_many_args(1, file, linenum, args, &err_code))
599 goto out;
600 if (global.maxconn != 0) {
601 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
602 err_code |= ERR_ALERT;
603 goto out;
604 }
605 if (*(args[1]) == 0) {
606 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
607 err_code |= ERR_ALERT | ERR_FATAL;
608 goto out;
609 }
610 global.maxconn = atol(args[1]);
611#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100612 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
613 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);
614 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100615 err_code |= ERR_ALERT;
616 }
617#endif /* SYSTEM_MAXCONN */
618 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100619 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100620 if (alertif_too_many_args(1, file, linenum, args, &err_code))
621 goto out;
622 if (*(args[1]) == 0) {
623 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
624 err_code |= ERR_ALERT | ERR_FATAL;
625 goto out;
626 }
627 if (strcmp(args[1],"none") == 0)
628 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
629 else if (strcmp(args[1],"required") == 0)
630 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
631 else {
632 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
633 err_code |= ERR_ALERT | ERR_FATAL;
634 goto out;
635 }
636 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100637 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100638 if (alertif_too_many_args(1, file, linenum, args, &err_code))
639 goto out;
640 if (global.cps_lim != 0) {
641 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
642 err_code |= ERR_ALERT;
643 goto out;
644 }
645 if (*(args[1]) == 0) {
646 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
647 err_code |= ERR_ALERT | ERR_FATAL;
648 goto out;
649 }
650 global.cps_lim = atol(args[1]);
651 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100652 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100653 if (alertif_too_many_args(1, file, linenum, args, &err_code))
654 goto out;
655 if (global.sps_lim != 0) {
656 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
657 err_code |= ERR_ALERT;
658 goto out;
659 }
660 if (*(args[1]) == 0) {
661 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
662 err_code |= ERR_ALERT | ERR_FATAL;
663 goto out;
664 }
665 global.sps_lim = atol(args[1]);
666 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100667 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100668 if (alertif_too_many_args(1, file, linenum, args, &err_code))
669 goto out;
670 if (global.ssl_lim != 0) {
671 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
672 err_code |= ERR_ALERT;
673 goto out;
674 }
675 if (*(args[1]) == 0) {
676 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
677 err_code |= ERR_ALERT | ERR_FATAL;
678 goto out;
679 }
680 global.ssl_lim = atol(args[1]);
681 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100682 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100683 if (alertif_too_many_args(1, file, linenum, args, &err_code))
684 goto out;
685 if (*(args[1]) == 0) {
686 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
687 err_code |= ERR_ALERT | ERR_FATAL;
688 goto out;
689 }
690 global.comp_rate_lim = atoi(args[1]) * 1024;
691 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100692 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100693 if (alertif_too_many_args(1, file, linenum, args, &err_code))
694 goto out;
695 if (global.maxpipes != 0) {
696 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
697 err_code |= ERR_ALERT;
698 goto out;
699 }
700 if (*(args[1]) == 0) {
701 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
702 err_code |= ERR_ALERT | ERR_FATAL;
703 goto out;
704 }
705 global.maxpipes = atol(args[1]);
706 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100707 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100708 if (alertif_too_many_args(1, file, linenum, args, &err_code))
709 goto out;
710 if (*(args[1]) == 0) {
711 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
712 err_code |= ERR_ALERT | ERR_FATAL;
713 goto out;
714 }
715 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
716 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100717 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100718 if (alertif_too_many_args(1, file, linenum, args, &err_code))
719 goto out;
720 if (*(args[1]) == 0) {
721 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
722 err_code |= ERR_ALERT | ERR_FATAL;
723 goto out;
724 }
725 compress_min_idle = 100 - atoi(args[1]);
726 if (compress_min_idle > 100) {
727 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
728 err_code |= ERR_ALERT | ERR_FATAL;
729 goto out;
730 }
731 }
732
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100733 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100734 if (alertif_too_many_args(1, file, linenum, args, &err_code))
735 goto out;
736 if (global.rlimit_nofile != 0) {
737 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
738 err_code |= ERR_ALERT;
739 goto out;
740 }
741 if (*(args[1]) == 0) {
742 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
743 err_code |= ERR_ALERT | ERR_FATAL;
744 goto out;
745 }
746 global.rlimit_nofile = atol(args[1]);
747 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100748 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100749 if (alertif_too_many_args(1, file, linenum, args, &err_code))
750 goto out;
751 if (global.chroot != NULL) {
752 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
753 err_code |= ERR_ALERT;
754 goto out;
755 }
756 if (*(args[1]) == 0) {
757 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
758 err_code |= ERR_ALERT | ERR_FATAL;
759 goto out;
760 }
761 global.chroot = strdup(args[1]);
762 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100763 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100764 int i, len=0;
765 char *d;
766
767 if (!*args[1]) {
768 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
769 file, linenum, args[0]);
770 err_code |= ERR_ALERT | ERR_FATAL;
771 goto out;
772 }
773
774 for (i = 1; *args[i]; i++)
775 len += strlen(args[i]) + 1;
776
777 if (global.desc)
778 free(global.desc);
779
780 global.desc = d = calloc(1, len);
781
782 d += snprintf(d, global.desc + len - d, "%s", args[1]);
783 for (i = 2; *args[i]; i++)
784 d += snprintf(d, global.desc + len - d, " %s", args[i]);
785 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100786 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100787 int i;
788 char c;
789
790 if (alertif_too_many_args(1, file, linenum, args, &err_code))
791 goto out;
792
793 for (i=0; args[1][i]; i++) {
794 c = args[1][i];
795 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
796 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
797 break;
798 }
799
800 if (!i || args[1][i]) {
801 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
802 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
803 file, linenum, args[0]);
804 err_code |= ERR_ALERT | ERR_FATAL;
805 goto out;
806 }
807
808 if (global.node)
809 free(global.node);
810
811 global.node = strdup(args[1]);
812 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100813 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100814 if (alertif_too_many_args(1, file, linenum, args, &err_code))
815 goto out;
816 if (global.pidfile != NULL) {
817 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
818 err_code |= ERR_ALERT;
819 goto out;
820 }
821 if (*(args[1]) == 0) {
822 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
823 err_code |= ERR_ALERT | ERR_FATAL;
824 goto out;
825 }
826 global.pidfile = strdup(args[1]);
827 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100828 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100829 int cur_arg = 1;
830 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100831 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100832 if (global.unix_bind.prefix != NULL) {
833 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
834 err_code |= ERR_ALERT;
835 cur_arg += 2;
836 continue;
837 }
838
839 if (*(args[cur_arg+1]) == 0) {
840 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
841 err_code |= ERR_ALERT | ERR_FATAL;
842 goto out;
843 }
844 global.unix_bind.prefix = strdup(args[cur_arg+1]);
845 cur_arg += 2;
846 continue;
847 }
848
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100849 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100850
851 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
852 cur_arg += 2;
853 continue;
854 }
855
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100856 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100857
858 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
859 cur_arg += 2;
860 continue;
861 }
862
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100863 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100864
865 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
866 cur_arg += 2;
867 continue;
868 }
869
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100870 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100871 struct passwd *user;
872
873 user = getpwnam(args[cur_arg + 1]);
874 if (!user) {
875 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
876 file, linenum, args[0], args[cur_arg + 1 ]);
877 err_code |= ERR_ALERT | ERR_FATAL;
878 goto out;
879 }
880
881 global.unix_bind.ux.uid = user->pw_uid;
882 cur_arg += 2;
883 continue;
884 }
885
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100886 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100887 struct group *group;
888
889 group = getgrnam(args[cur_arg + 1]);
890 if (!group) {
891 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
892 file, linenum, args[0], args[cur_arg + 1 ]);
893 err_code |= ERR_ALERT | ERR_FATAL;
894 goto out;
895 }
896
897 global.unix_bind.ux.gid = group->gr_gid;
898 cur_arg += 2;
899 continue;
900 }
901
902 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
903 file, linenum, args[0]);
904 err_code |= ERR_ALERT | ERR_FATAL;
905 goto out;
906 }
907 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100908 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200909 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100910 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
911 err_code |= ERR_ALERT | ERR_FATAL;
912 goto out;
913 }
914 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100915 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100916 char *name;
917
918 if (global.log_send_hostname != NULL) {
919 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
920 err_code |= ERR_ALERT;
921 goto out;
922 }
923
924 if (*(args[1]))
925 name = args[1];
926 else
927 name = hostname;
928
929 free(global.log_send_hostname);
930 global.log_send_hostname = strdup(name);
931 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100932 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 +0100933 if (global.server_state_base != NULL) {
934 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
935 err_code |= ERR_ALERT;
936 goto out;
937 }
938
939 if (!*(args[1])) {
940 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
941 err_code |= ERR_FATAL;
942 goto out;
943 }
944
945 global.server_state_base = strdup(args[1]);
946 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100947 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 +0100948 if (global.server_state_file != NULL) {
949 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
950 err_code |= ERR_ALERT;
951 goto out;
952 }
953
954 if (!*(args[1])) {
955 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
956 err_code |= ERR_FATAL;
957 goto out;
958 }
959
960 global.server_state_file = strdup(args[1]);
961 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100962 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100963 if (alertif_too_many_args(1, file, linenum, args, &err_code))
964 goto out;
965 if (*(args[1]) == 0) {
966 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
967 err_code |= ERR_ALERT | ERR_FATAL;
968 goto out;
969 }
970 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +0200971 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
972 if (b_orig(&global.log_tag) == NULL) {
973 chunk_destroy(&global.log_tag);
974 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
975 err_code |= ERR_ALERT | ERR_FATAL;
976 goto out;
977 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100978 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100979 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100980 if (alertif_too_many_args(1, file, linenum, args, &err_code))
981 goto out;
982 if (global.spread_checks != 0) {
983 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
984 err_code |= ERR_ALERT;
985 goto out;
986 }
987 if (*(args[1]) == 0) {
988 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
989 err_code |= ERR_ALERT | ERR_FATAL;
990 goto out;
991 }
992 global.spread_checks = atol(args[1]);
993 if (global.spread_checks < 0 || global.spread_checks > 50) {
994 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
995 err_code |= ERR_ALERT | ERR_FATAL;
996 }
997 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100998 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100999 const char *err;
1000 unsigned int val;
1001
1002 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1003 goto out;
1004 if (*(args[1]) == 0) {
1005 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1006 err_code |= ERR_ALERT | ERR_FATAL;
1007 goto out;
1008 }
1009
1010 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001011 if (err == PARSE_TIME_OVER) {
1012 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1013 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001014 err_code |= ERR_ALERT | ERR_FATAL;
1015 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001016 else if (err == PARSE_TIME_UNDER) {
1017 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1018 file, linenum, args[1], args[0]);
1019 err_code |= ERR_ALERT | ERR_FATAL;
1020 }
1021 else if (err) {
1022 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 +01001023 err_code |= ERR_ALERT | ERR_FATAL;
1024 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001025 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001026 }
1027 else if (strcmp(args[0], "cpu-map") == 0) {
1028 /* map a process list to a CPU set */
1029#ifdef USE_CPU_AFFINITY
1030 char *slash;
1031 unsigned long proc = 0, thread = 0, cpus;
Amaury Denoyellec90932b2021-04-14 16:16:03 +02001032 int i, j, n, k, autoinc;
1033 struct hap_cpuset cpuset;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001034
1035 if (!*args[1] || !*args[2]) {
1036 ha_alert("parsing [%s:%d] : %s expects a process number "
1037 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1038 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001039 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001040 err_code |= ERR_ALERT | ERR_FATAL;
1041 goto out;
1042 }
1043
1044 if ((slash = strchr(args[1], '/')) != NULL)
1045 *slash = 0;
1046
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001047 /* note: we silently ignore processes over MAX_PROCS and
1048 * threads over MAX_THREADS so as not to make configurations a
1049 * pain to maintain.
1050 */
1051 if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001052 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1053 err_code |= ERR_ALERT | ERR_FATAL;
1054 goto out;
1055 }
1056
1057 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001058 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001059 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1060 err_code |= ERR_ALERT | ERR_FATAL;
1061 goto out;
1062 }
1063 *slash = '/';
1064
1065 if (autoinc && atleast2(proc) && atleast2(thread)) {
1066 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1067 "a process range _AND_ a thread range\n",
1068 file, linenum, args[0], args[1]);
1069 err_code |= ERR_ALERT | ERR_FATAL;
1070 goto out;
1071 }
1072 }
1073
Amaury Denoyellec90932b2021-04-14 16:16:03 +02001074 if (parse_cpu_set((const char **)args+2, &cpuset, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001075 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1076 err_code |= ERR_ALERT | ERR_FATAL;
1077 goto out;
1078 }
Amaury Denoyellec90932b2021-04-14 16:16:03 +02001079#if defined(CPUSET_USE_CPUSET)
1080 k = 0;
1081 while (CPU_COUNT(&cpuset.cpuset)) {
1082 while (!CPU_ISSET(k, &cpuset.cpuset))
1083 ++k;
1084 cpus |= 1 << k;
1085 CPU_CLR(k, &cpuset.cpuset);
1086 ++k;
1087 }
1088#elif defined(CPUSET_USE_ULONG)
1089 cpus = cpuset.cpuset;
1090#endif
Willy Tarreau36b9e222018-11-11 15:19:52 +01001091 if (autoinc &&
1092 my_popcountl(proc) != my_popcountl(cpus) &&
1093 my_popcountl(thread) != my_popcountl(cpus)) {
1094 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1095 "must have the same size to be automatically bound\n",
1096 file, linenum, args[0]);
1097 err_code |= ERR_ALERT | ERR_FATAL;
1098 goto out;
1099 }
1100
Willy Tarreau7764a572019-07-16 15:10:34 +02001101 /* we now have to deal with 3 real cases :
1102 * cpu-map P-Q => mapping for whole processes, numbers P to Q
1103 * cpu-map P-Q/1 => mapping of first thread of processes P to Q
1104 * cpu-map 1/T-U => mapping of threads T to U of process 1
1105 * Otherwise other combinations are silently ignored since nbthread
1106 * and nbproc cannot both be >1 :
1107 * cpu-map P-Q/T => mapping for thread T for processes P to Q.
1108 * Only one of T,Q may be > 1, others ignored.
1109 * cpu-map P/T-U => mapping for threads T to U of process P. Only
1110 * one of P,U may be > 1, others ignored.
1111 */
1112 if (!thread) {
1113 /* mapping for whole processes. E.g. cpu-map 1-4 0-3 */
Willy Tarreau81492c92019-05-03 09:41:23 +02001114 for (i = n = 0; i < MAX_PROCS; i++) {
1115 /* No mapping for this process */
1116 if (!(proc & (1UL << i)))
1117 continue;
1118
Willy Tarreau36b9e222018-11-11 15:19:52 +01001119 if (!autoinc)
1120 global.cpu_map.proc[i] = cpus;
1121 else {
1122 n += my_ffsl(cpus >> n);
1123 global.cpu_map.proc[i] = (1UL << (n-1));
1124 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001125 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001126 } else {
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001127 /* Mapping at the thread level.
1128 * Either proc and/or thread must be 1 and only 1. All
1129 * other combinations are silently ignored.
Willy Tarreau7764a572019-07-16 15:10:34 +02001130 */
1131 if (thread == 0x1) {
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001132 int val;
1133
Willy Tarreau7764a572019-07-16 15:10:34 +02001134 /* first thread, iterate on processes. E.g. cpu-map 1-4/1 0-3 */
1135 for (i = n = 0; i < MAX_PROCS; i++) {
1136 /* No mapping for this process */
1137 if (!(proc & (1UL << i)))
1138 continue;
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001139
1140 if (!autoinc) {
1141 val = cpus;
1142 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001143 else {
1144 n += my_ffsl(cpus >> n);
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001145 val = 1UL << (n - 1);
Willy Tarreau7764a572019-07-16 15:10:34 +02001146 }
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001147
1148 /* For first process, thread[0] is used.
1149 * Use proc_t1[N] for all others
1150 */
1151 if (!i)
1152 global.cpu_map.thread[0] = val;
1153 else
1154 global.cpu_map.proc_t1[i] = val;
Willy Tarreau7764a572019-07-16 15:10:34 +02001155 }
1156 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001157
Willy Tarreau7764a572019-07-16 15:10:34 +02001158 if (proc == 0x1) {
1159 /* first process, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
1160 for (j = n = 0; j < MAX_THREADS; j++) {
1161 /* No mapping for this thread */
1162 if (!(thread & (1UL << j)))
1163 continue;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001164
Willy Tarreau7764a572019-07-16 15:10:34 +02001165 if (!autoinc)
1166 global.cpu_map.thread[j] = cpus;
1167 else {
1168 n += my_ffsl(cpus >> n);
1169 global.cpu_map.thread[j] = (1UL << (n-1));
1170 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001171 }
1172 }
Amaury Denoyellea2944ec2021-04-15 18:07:07 +02001173
1174 HA_DIAG_WARNING_COND(proc != 0x1 && thread != 0x1,
1175 "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 +01001176 }
1177#else
1178 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1179 file, linenum, args[0]);
1180 err_code |= ERR_ALERT | ERR_FATAL;
1181 goto out;
1182#endif /* ! USE_CPU_AFFINITY */
1183 }
1184 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1185 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1186 goto out;
1187
1188 if (*(args[2]) == 0) {
1189 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1190 err_code |= ERR_ALERT | ERR_FATAL;
1191 goto out;
1192 }
1193
1194 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1195 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1196 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1197 err_code |= ERR_ALERT | ERR_FATAL;
1198 goto out;
1199 }
1200 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001201 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001202 int arg;
1203
1204 if (*(args[1]) == 0) {
1205 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1206 err_code |= ERR_ALERT | ERR_FATAL;
1207 goto out;
1208 }
1209
1210 for (arg = 1; *args[arg]; arg++) {
1211 if (unsetenv(args[arg]) != 0) {
1212 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1213 err_code |= ERR_ALERT | ERR_FATAL;
1214 goto out;
1215 }
1216 }
1217 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001218 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001219 extern char **environ;
1220 char **env = environ;
1221
1222 /* args contain variable names to keep, one per argument */
1223 while (*env) {
1224 int arg;
1225
1226 /* look for current variable in among all those we want to keep */
1227 for (arg = 1; *args[arg]; arg++) {
1228 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1229 (*env)[strlen(args[arg])] == '=')
1230 break;
1231 }
1232
1233 /* delete this variable */
1234 if (!*args[arg]) {
1235 char *delim = strchr(*env, '=');
1236
1237 if (!delim || delim - *env >= trash.size) {
1238 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1239 err_code |= ERR_ALERT | ERR_FATAL;
1240 goto out;
1241 }
1242
1243 memcpy(trash.area, *env, delim - *env);
1244 trash.area[delim - *env] = 0;
1245
1246 if (unsetenv(trash.area) != 0) {
1247 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1248 err_code |= ERR_ALERT | ERR_FATAL;
1249 goto out;
1250 }
1251 }
1252 else
1253 env++;
1254 }
1255 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001256 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001257 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1258 goto out;
1259 if (kwm == KWM_NO)
1260 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001261 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001262 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001263 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1264 goto out;
1265
1266 if (*(args[1]) == 0) {
1267 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1268 file, linenum, args[0]);
1269 err_code |= ERR_ALERT | ERR_FATAL;
1270 goto out;
1271 }
1272
1273 if (global.localpeer_cmdline != 0) {
1274 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1275 "command line argument.\n", file, linenum, args[0]);
1276 err_code |= ERR_WARN;
1277 goto out;
1278 }
1279
1280 if (cfg_peers) {
1281 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1282 file, linenum, args[0]);
1283 err_code |= ERR_WARN;
1284 goto out;
1285 }
1286
1287 free(localpeer);
1288 if ((localpeer = strdup(args[1])) == NULL) {
1289 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1290 file, linenum, args[0]);
1291 err_code |= ERR_ALERT | ERR_FATAL;
1292 goto out;
1293 }
1294 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1295 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001296 else {
1297 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001298 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001299 int index;
1300 int rc;
1301
1302 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1303 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1304 if (kwl->kw[index].section != CFG_GLOBAL)
1305 continue;
1306 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
1307 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1308 if (rc < 0) {
1309 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1310 err_code |= ERR_ALERT | ERR_FATAL;
1311 }
1312 else if (rc > 0) {
1313 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1314 err_code |= ERR_WARN;
1315 goto out;
1316 }
1317 goto out;
1318 }
1319 }
1320 }
1321
Willy Tarreau101df312021-03-15 09:12:41 +01001322 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001323 if (best)
1324 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1325 else
1326 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001327 err_code |= ERR_ALERT | ERR_FATAL;
1328 }
1329
1330 out:
1331 free(errmsg);
1332 return err_code;
1333}
1334