blob: b539a97ca005ca5c60cf054fa0ff59bcdefbd631 [file] [log] [blame]
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001#define _GNU_SOURCE /* for cpu_set_t from haproxy/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 Denoyellea6f9c5d2021-04-23 16:58:08 +020017#ifdef USE_CPU_AFFINITY
Amaury Denoyellec90932b2021-04-14 16:16:03 +020018#include <haproxy/cpuset.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020019#endif
Willy Tarreau0a3bd392020-06-04 08:52:38 +020020#include <haproxy/compression.h>
Willy Tarreaudfd3de82020-06-04 23:46:14 +020021#include <haproxy/global.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020022#include <haproxy/log.h>
Dragan Dosen13cd54c2020-06-18 18:24:05 +020023#include <haproxy/peers.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020024#include <haproxy/tools.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010025
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010026/* some keywords that are still being parsed using strcmp() and are not
27 * registered anywhere. They are used as suggestions for mistyped words.
28 */
29static const char *common_kw_list[] = {
30 "global", "daemon", "master-worker", "noepoll", "nokqueue",
31 "noevports", "nopoll", "busy-polling", "set-dumpable",
32 "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
33 "nogetaddrinfo", "noreuseport", "quiet", "zero-warning",
34 "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept",
35 "tune.chksize", "tune.recv_enough", "tune.buffers.limit",
36 "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite",
37 "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server",
38 "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize",
39 "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr",
40 "tune.comp.maxlevel", "tune.pattern.cache-size", "uid", "gid",
41 "external-check", "user", "group", "nbproc", "nbthread", "maxconn",
42 "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
43 "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n",
44 "chroot", "description", "node", "pidfile", "unix-bind", "log",
45 "log-send-hostname", "server-state-base", "server-state-file",
46 "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv",
47 "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer",
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +010048 "numa-cpu-mapping", "defaults", "listen", "frontend", "backend",
49 "peers", "resolvers",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010050 NULL /* must be last */
51};
52
Willy Tarreau36b9e222018-11-11 15:19:52 +010053/*
54 * parse a line in a <global> section. Returns the error code, 0 if OK, or
55 * any combination of :
56 * - ERR_ABORT: must abort ASAP
57 * - ERR_FATAL: we can continue parsing but not start the service
58 * - ERR_WARN: a warning has been emitted
59 * - ERR_ALERT: an alert has been emitted
60 * Only the two first ones can stop processing, the two others are just
61 * indicators.
62 */
63int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
64{
65 int err_code = 0;
66 char *errmsg = NULL;
67
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010068 if (strcmp(args[0], "global") == 0) { /* new section */
Willy Tarreau36b9e222018-11-11 15:19:52 +010069 /* no option, nothing special to do */
70 alertif_too_many_args(0, file, linenum, args, &err_code);
71 goto out;
72 }
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +020073 else if (strcmp(args[0], "expose-experimental-directives") == 0) {
74 experimental_directives_allowed = 1;
75 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010076 else if (strcmp(args[0], "daemon") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010077 if (alertif_too_many_args(0, file, linenum, args, &err_code))
78 goto out;
79 global.mode |= MODE_DAEMON;
80 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010081 else if (strcmp(args[0], "master-worker") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010082 if (alertif_too_many_args(1, file, linenum, args, &err_code))
83 goto out;
84 if (*args[1]) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010085 if (strcmp(args[1], "no-exit-on-failure") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010086 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
87 } else {
88 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
89 err_code |= ERR_ALERT | ERR_FATAL;
90 goto out;
91 }
92 }
93 global.mode |= MODE_MWORKER;
94 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010095 else if (strcmp(args[0], "noepoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010096 if (alertif_too_many_args(0, file, linenum, args, &err_code))
97 goto out;
98 global.tune.options &= ~GTUNE_USE_EPOLL;
99 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100100 else if (strcmp(args[0], "nokqueue") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100101 if (alertif_too_many_args(0, file, linenum, args, &err_code))
102 goto out;
103 global.tune.options &= ~GTUNE_USE_KQUEUE;
104 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100105 else if (strcmp(args[0], "noevports") == 0) {
Emmanuel Hocdet0ba4f482019-04-08 16:53:32 +0000106 if (alertif_too_many_args(0, file, linenum, args, &err_code))
107 goto out;
108 global.tune.options &= ~GTUNE_USE_EVPORTS;
109 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100110 else if (strcmp(args[0], "nopoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100111 if (alertif_too_many_args(0, file, linenum, args, &err_code))
112 goto out;
113 global.tune.options &= ~GTUNE_USE_POLL;
114 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100115 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100116 if (alertif_too_many_args(0, file, linenum, args, &err_code))
117 goto out;
118 if (kwm == KWM_NO)
119 global.tune.options &= ~GTUNE_BUSY_POLLING;
120 else
121 global.tune.options |= GTUNE_BUSY_POLLING;
122 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100123 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200124 if (alertif_too_many_args(0, file, linenum, args, &err_code))
125 goto out;
126 if (kwm == KWM_NO)
127 global.tune.options &= ~GTUNE_SET_DUMPABLE;
128 else
129 global.tune.options |= GTUNE_SET_DUMPABLE;
130 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100131 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100132 if (alertif_too_many_args(0, file, linenum, args, &err_code))
133 goto out;
134 if (kwm == KWM_NO)
135 global.tune.options &= ~GTUNE_INSECURE_FORK;
136 else
137 global.tune.options |= GTUNE_INSECURE_FORK;
138 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100139 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100140 if (alertif_too_many_args(0, file, linenum, args, &err_code))
141 goto out;
142 if (kwm == KWM_NO)
143 global.tune.options &= ~GTUNE_INSECURE_SETUID;
144 else
145 global.tune.options |= GTUNE_INSECURE_SETUID;
146 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100147 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100148 if (alertif_too_many_args(0, file, linenum, args, &err_code))
149 goto out;
150 global.tune.options &= ~GTUNE_USE_SPLICE;
151 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100152 else if (strcmp(args[0], "nogetaddrinfo") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100153 if (alertif_too_many_args(0, file, linenum, args, &err_code))
154 goto out;
155 global.tune.options &= ~GTUNE_USE_GAI;
156 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100157 else if (strcmp(args[0], "noreuseport") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100158 if (alertif_too_many_args(0, file, linenum, args, &err_code))
159 goto out;
160 global.tune.options &= ~GTUNE_USE_REUSEPORT;
161 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100162 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100163 if (alertif_too_many_args(0, file, linenum, args, &err_code))
164 goto out;
165 global.mode |= MODE_QUIET;
166 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100167 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200168 if (alertif_too_many_args(0, file, linenum, args, &err_code))
169 goto out;
170 global.mode |= MODE_ZERO_WARNING;
171 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100172 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100173 if (alertif_too_many_args(1, file, linenum, args, &err_code))
174 goto out;
175 if (global.tune.runqueue_depth != 0) {
176 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
177 err_code |= ERR_ALERT;
178 goto out;
179 }
180 if (*(args[1]) == 0) {
181 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
182 err_code |= ERR_ALERT | ERR_FATAL;
183 goto out;
184 }
185 global.tune.runqueue_depth = atol(args[1]);
186
187 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100188 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100189 if (alertif_too_many_args(1, file, linenum, args, &err_code))
190 goto out;
191 if (global.tune.maxpollevents != 0) {
192 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
193 err_code |= ERR_ALERT;
194 goto out;
195 }
196 if (*(args[1]) == 0) {
197 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
198 err_code |= ERR_ALERT | ERR_FATAL;
199 goto out;
200 }
201 global.tune.maxpollevents = atol(args[1]);
202 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100203 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200204 long max;
205
Willy Tarreau36b9e222018-11-11 15:19:52 +0100206 if (alertif_too_many_args(1, file, linenum, args, &err_code))
207 goto out;
208 if (global.tune.maxaccept != 0) {
209 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
210 err_code |= ERR_ALERT;
211 goto out;
212 }
213 if (*(args[1]) == 0) {
214 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
215 err_code |= ERR_ALERT | ERR_FATAL;
216 goto out;
217 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200218 max = atol(args[1]);
219 if (/*max < -1 || */max > INT_MAX) {
220 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
221 err_code |= ERR_ALERT | ERR_FATAL;
222 goto out;
223 }
224 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100225 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100226 else if (strcmp(args[0], "tune.chksize") == 0) {
Christopher Fauletf8c869b2020-11-25 17:33:03 +0100227 ha_warning("parsing [%s:%d]: the option '%s' is deprecated and will be removed in next version.\n",
228 file, linenum, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100229 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100230 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100231 if (alertif_too_many_args(1, file, linenum, args, &err_code))
232 goto out;
233 if (*(args[1]) == 0) {
234 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
235 err_code |= ERR_ALERT | ERR_FATAL;
236 goto out;
237 }
238 global.tune.recv_enough = atol(args[1]);
239 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100240 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100241 if (alertif_too_many_args(1, file, linenum, args, &err_code))
242 goto out;
243 if (*(args[1]) == 0) {
244 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
245 err_code |= ERR_ALERT | ERR_FATAL;
246 goto out;
247 }
248 global.tune.buf_limit = atol(args[1]);
249 if (global.tune.buf_limit) {
250 if (global.tune.buf_limit < 3)
251 global.tune.buf_limit = 3;
252 if (global.tune.buf_limit <= global.tune.reserved_bufs)
253 global.tune.buf_limit = global.tune.reserved_bufs + 1;
254 }
255 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100256 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100257 if (alertif_too_many_args(1, file, linenum, args, &err_code))
258 goto out;
259 if (*(args[1]) == 0) {
260 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
261 err_code |= ERR_ALERT | ERR_FATAL;
262 goto out;
263 }
264 global.tune.reserved_bufs = atol(args[1]);
265 if (global.tune.reserved_bufs < 2)
266 global.tune.reserved_bufs = 2;
267 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
268 global.tune.buf_limit = global.tune.reserved_bufs + 1;
269 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100270 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100271 if (alertif_too_many_args(1, file, linenum, args, &err_code))
272 goto out;
273 if (*(args[1]) == 0) {
274 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
275 err_code |= ERR_ALERT | ERR_FATAL;
276 goto out;
277 }
278 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100279 /* round it up to support a two-pointer alignment at the end */
280 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100281 if (global.tune.bufsize <= 0) {
282 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
283 err_code |= ERR_ALERT | ERR_FATAL;
284 goto out;
285 }
286 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100287 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100288 if (alertif_too_many_args(1, file, linenum, args, &err_code))
289 goto out;
290 if (*(args[1]) == 0) {
291 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
292 err_code |= ERR_ALERT | ERR_FATAL;
293 goto out;
294 }
295 global.tune.maxrewrite = atol(args[1]);
296 if (global.tune.maxrewrite < 0) {
297 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
298 err_code |= ERR_ALERT | ERR_FATAL;
299 goto out;
300 }
301 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100302 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100303 unsigned int idle;
304 const char *res;
305
306 if (alertif_too_many_args(1, file, linenum, args, &err_code))
307 goto out;
308 if (*(args[1]) == 0) {
309 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
310 err_code |= ERR_ALERT | ERR_FATAL;
311 goto out;
312 }
313
314 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200315 if (res == PARSE_TIME_OVER) {
316 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
317 file, linenum, args[1], args[0]);
318 err_code |= ERR_ALERT | ERR_FATAL;
319 goto out;
320 }
321 else if (res == PARSE_TIME_UNDER) {
322 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
323 file, linenum, args[1], args[0]);
324 err_code |= ERR_ALERT | ERR_FATAL;
325 goto out;
326 }
327 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100328 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200329 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100330 err_code |= ERR_ALERT | ERR_FATAL;
331 goto out;
332 }
333
334 if (idle > 65535) {
335 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
336 err_code |= ERR_ALERT | ERR_FATAL;
337 goto out;
338 }
339 global.tune.idle_timer = idle;
340 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100341 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100342 if (alertif_too_many_args(1, file, linenum, args, &err_code))
343 goto out;
344 if (global.tune.client_rcvbuf != 0) {
345 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
346 err_code |= ERR_ALERT;
347 goto out;
348 }
349 if (*(args[1]) == 0) {
350 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
351 err_code |= ERR_ALERT | ERR_FATAL;
352 goto out;
353 }
354 global.tune.client_rcvbuf = atol(args[1]);
355 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100356 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100357 if (alertif_too_many_args(1, file, linenum, args, &err_code))
358 goto out;
359 if (global.tune.server_rcvbuf != 0) {
360 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
361 err_code |= ERR_ALERT;
362 goto out;
363 }
364 if (*(args[1]) == 0) {
365 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
366 err_code |= ERR_ALERT | ERR_FATAL;
367 goto out;
368 }
369 global.tune.server_rcvbuf = atol(args[1]);
370 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100371 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100372 if (alertif_too_many_args(1, file, linenum, args, &err_code))
373 goto out;
374 if (global.tune.client_sndbuf != 0) {
375 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
376 err_code |= ERR_ALERT;
377 goto out;
378 }
379 if (*(args[1]) == 0) {
380 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
381 err_code |= ERR_ALERT | ERR_FATAL;
382 goto out;
383 }
384 global.tune.client_sndbuf = atol(args[1]);
385 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100386 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100387 if (alertif_too_many_args(1, file, linenum, args, &err_code))
388 goto out;
389 if (global.tune.server_sndbuf != 0) {
390 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
391 err_code |= ERR_ALERT;
392 goto out;
393 }
394 if (*(args[1]) == 0) {
395 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
396 err_code |= ERR_ALERT | ERR_FATAL;
397 goto out;
398 }
399 global.tune.server_sndbuf = atol(args[1]);
400 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100401 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100402 if (alertif_too_many_args(1, file, linenum, args, &err_code))
403 goto out;
404 if (*(args[1]) == 0) {
405 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
406 err_code |= ERR_ALERT | ERR_FATAL;
407 goto out;
408 }
409 global.tune.pipesize = atol(args[1]);
410 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100411 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100412 if (alertif_too_many_args(1, file, linenum, args, &err_code))
413 goto out;
414 if (*(args[1]) == 0) {
415 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
416 err_code |= ERR_ALERT | ERR_FATAL;
417 goto out;
418 }
419 global.tune.cookie_len = atol(args[1]) + 1;
420 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100421 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100422 if (alertif_too_many_args(1, file, linenum, args, &err_code))
423 goto out;
424 if (*(args[1]) == 0) {
425 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
426 err_code |= ERR_ALERT | ERR_FATAL;
427 goto out;
428 }
429 global.tune.requri_len = atol(args[1]) + 1;
430 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100431 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100432 if (alertif_too_many_args(1, file, linenum, args, &err_code))
433 goto out;
434 if (*(args[1]) == 0) {
435 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
436 err_code |= ERR_ALERT | ERR_FATAL;
437 goto out;
438 }
439 global.tune.max_http_hdr = atoi(args[1]);
440 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
441 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
442 file, linenum, args[0]);
443 err_code |= ERR_ALERT | ERR_FATAL;
444 goto out;
445 }
446 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100447 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100448 if (alertif_too_many_args(1, file, linenum, args, &err_code))
449 goto out;
450 if (*args[1]) {
451 global.tune.comp_maxlevel = atoi(args[1]);
452 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
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 } else {
459 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
460 file, linenum, args[0]);
461 err_code |= ERR_ALERT | ERR_FATAL;
462 goto out;
463 }
464 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100465 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100466 if (*args[1]) {
467 global.tune.pattern_cache = atoi(args[1]);
468 if (global.tune.pattern_cache < 0) {
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 } else {
475 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
476 file, linenum, args[0]);
477 err_code |= ERR_ALERT | ERR_FATAL;
478 goto out;
479 }
480 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100481 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100482 if (alertif_too_many_args(1, file, linenum, args, &err_code))
483 goto out;
484 if (global.uid != 0) {
485 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
486 err_code |= ERR_ALERT;
487 goto out;
488 }
489 if (*(args[1]) == 0) {
490 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
491 err_code |= ERR_ALERT | ERR_FATAL;
492 goto out;
493 }
494 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
495 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]);
496 err_code |= ERR_WARN;
497 goto out;
498 }
499
500 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100501 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100502 if (alertif_too_many_args(1, file, linenum, args, &err_code))
503 goto out;
504 if (global.gid != 0) {
505 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
506 err_code |= ERR_ALERT;
507 goto out;
508 }
509 if (*(args[1]) == 0) {
510 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
511 err_code |= ERR_ALERT | ERR_FATAL;
512 goto out;
513 }
514 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
515 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]);
516 err_code |= ERR_WARN;
517 goto out;
518 }
519 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100520 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100521 if (alertif_too_many_args(0, file, linenum, args, &err_code))
522 goto out;
523 global.external_check = 1;
524 }
525 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100526 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100527 struct passwd *ha_user;
528 if (alertif_too_many_args(1, file, linenum, args, &err_code))
529 goto out;
530 if (global.uid != 0) {
531 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
532 err_code |= ERR_ALERT;
533 goto out;
534 }
535 errno = 0;
536 ha_user = getpwnam(args[1]);
537 if (ha_user != NULL) {
538 global.uid = (int)ha_user->pw_uid;
539 }
540 else {
541 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
542 err_code |= ERR_ALERT | ERR_FATAL;
543 }
544 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100545 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100546 struct group *ha_group;
547 if (alertif_too_many_args(1, file, linenum, args, &err_code))
548 goto out;
549 if (global.gid != 0) {
550 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
551 err_code |= ERR_ALERT;
552 goto out;
553 }
554 errno = 0;
555 ha_group = getgrnam(args[1]);
556 if (ha_group != NULL) {
557 global.gid = (int)ha_group->gr_gid;
558 }
559 else {
560 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
561 err_code |= ERR_ALERT | ERR_FATAL;
562 }
563 }
564 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100565 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100566 if (alertif_too_many_args(1, file, linenum, args, &err_code))
567 goto out;
568 if (*(args[1]) == 0) {
569 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
570 err_code |= ERR_ALERT | ERR_FATAL;
571 goto out;
572 }
573 global.nbproc = atol(args[1]);
Willy Tarreaua38a7172019-02-02 17:11:28 +0100574 all_proc_mask = nbits(global.nbproc);
Willy Tarreauff9c9142019-02-07 10:39:36 +0100575 if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100576 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
Willy Tarreauff9c9142019-02-07 10:39:36 +0100577 file, linenum, args[0], MAX_PROCS, global.nbproc);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100578 err_code |= ERR_ALERT | ERR_FATAL;
579 goto out;
580 }
581 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100582 else if (strcmp(args[0], "nbthread") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100583 if (alertif_too_many_args(1, file, linenum, args, &err_code))
584 goto out;
585 if (*(args[1]) == 0) {
586 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
587 err_code |= ERR_ALERT | ERR_FATAL;
588 goto out;
589 }
Amaury Denoyellec4d47d62021-03-29 10:41:15 +0200590
591 HA_DIAG_WARNING_COND(global.nbthread,
592 "parsing [%s:%d] : nbthread is already defined and will be overridden.\n",
593 file, linenum);
594
Willy Tarreau36b9e222018-11-11 15:19:52 +0100595 global.nbthread = parse_nbthread(args[1], &errmsg);
596 if (!global.nbthread) {
597 ha_alert("parsing [%s:%d] : '%s' %s.\n",
598 file, linenum, args[0], errmsg);
599 err_code |= ERR_ALERT | ERR_FATAL;
600 goto out;
601 }
602 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100603 else if (strcmp(args[0], "maxconn") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100604 if (alertif_too_many_args(1, file, linenum, args, &err_code))
605 goto out;
606 if (global.maxconn != 0) {
607 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
608 err_code |= ERR_ALERT;
609 goto out;
610 }
611 if (*(args[1]) == 0) {
612 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
613 err_code |= ERR_ALERT | ERR_FATAL;
614 goto out;
615 }
616 global.maxconn = atol(args[1]);
617#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100618 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
619 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);
620 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100621 err_code |= ERR_ALERT;
622 }
623#endif /* SYSTEM_MAXCONN */
624 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100625 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100626 if (alertif_too_many_args(1, file, linenum, args, &err_code))
627 goto out;
628 if (*(args[1]) == 0) {
629 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
630 err_code |= ERR_ALERT | ERR_FATAL;
631 goto out;
632 }
633 if (strcmp(args[1],"none") == 0)
634 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
635 else if (strcmp(args[1],"required") == 0)
636 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
637 else {
638 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
639 err_code |= ERR_ALERT | ERR_FATAL;
640 goto out;
641 }
642 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100643 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100644 if (alertif_too_many_args(1, file, linenum, args, &err_code))
645 goto out;
646 if (global.cps_lim != 0) {
647 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
648 err_code |= ERR_ALERT;
649 goto out;
650 }
651 if (*(args[1]) == 0) {
652 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
653 err_code |= ERR_ALERT | ERR_FATAL;
654 goto out;
655 }
656 global.cps_lim = atol(args[1]);
657 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100658 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100659 if (alertif_too_many_args(1, file, linenum, args, &err_code))
660 goto out;
661 if (global.sps_lim != 0) {
662 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
663 err_code |= ERR_ALERT;
664 goto out;
665 }
666 if (*(args[1]) == 0) {
667 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
668 err_code |= ERR_ALERT | ERR_FATAL;
669 goto out;
670 }
671 global.sps_lim = atol(args[1]);
672 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100673 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100674 if (alertif_too_many_args(1, file, linenum, args, &err_code))
675 goto out;
676 if (global.ssl_lim != 0) {
677 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
678 err_code |= ERR_ALERT;
679 goto out;
680 }
681 if (*(args[1]) == 0) {
682 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
683 err_code |= ERR_ALERT | ERR_FATAL;
684 goto out;
685 }
686 global.ssl_lim = atol(args[1]);
687 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100688 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100689 if (alertif_too_many_args(1, file, linenum, args, &err_code))
690 goto out;
691 if (*(args[1]) == 0) {
692 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
693 err_code |= ERR_ALERT | ERR_FATAL;
694 goto out;
695 }
696 global.comp_rate_lim = atoi(args[1]) * 1024;
697 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100698 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100699 if (alertif_too_many_args(1, file, linenum, args, &err_code))
700 goto out;
701 if (global.maxpipes != 0) {
702 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
703 err_code |= ERR_ALERT;
704 goto out;
705 }
706 if (*(args[1]) == 0) {
707 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
708 err_code |= ERR_ALERT | ERR_FATAL;
709 goto out;
710 }
711 global.maxpipes = atol(args[1]);
712 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100713 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100714 if (alertif_too_many_args(1, file, linenum, args, &err_code))
715 goto out;
716 if (*(args[1]) == 0) {
717 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
718 err_code |= ERR_ALERT | ERR_FATAL;
719 goto out;
720 }
721 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
722 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100723 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100724 if (alertif_too_many_args(1, file, linenum, args, &err_code))
725 goto out;
726 if (*(args[1]) == 0) {
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 compress_min_idle = 100 - atoi(args[1]);
732 if (compress_min_idle > 100) {
733 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
734 err_code |= ERR_ALERT | ERR_FATAL;
735 goto out;
736 }
737 }
738
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100739 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100740 if (alertif_too_many_args(1, file, linenum, args, &err_code))
741 goto out;
742 if (global.rlimit_nofile != 0) {
743 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
744 err_code |= ERR_ALERT;
745 goto out;
746 }
747 if (*(args[1]) == 0) {
748 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
749 err_code |= ERR_ALERT | ERR_FATAL;
750 goto out;
751 }
752 global.rlimit_nofile = atol(args[1]);
753 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100754 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100755 if (alertif_too_many_args(1, file, linenum, args, &err_code))
756 goto out;
757 if (global.chroot != NULL) {
758 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
759 err_code |= ERR_ALERT;
760 goto out;
761 }
762 if (*(args[1]) == 0) {
763 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
764 err_code |= ERR_ALERT | ERR_FATAL;
765 goto out;
766 }
767 global.chroot = strdup(args[1]);
768 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100769 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100770 int i, len=0;
771 char *d;
772
773 if (!*args[1]) {
774 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
775 file, linenum, args[0]);
776 err_code |= ERR_ALERT | ERR_FATAL;
777 goto out;
778 }
779
780 for (i = 1; *args[i]; i++)
781 len += strlen(args[i]) + 1;
782
783 if (global.desc)
784 free(global.desc);
785
786 global.desc = d = calloc(1, len);
787
788 d += snprintf(d, global.desc + len - d, "%s", args[1]);
789 for (i = 2; *args[i]; i++)
790 d += snprintf(d, global.desc + len - d, " %s", args[i]);
791 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100792 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100793 int i;
794 char c;
795
796 if (alertif_too_many_args(1, file, linenum, args, &err_code))
797 goto out;
798
799 for (i=0; args[1][i]; i++) {
800 c = args[1][i];
801 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
802 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
803 break;
804 }
805
806 if (!i || args[1][i]) {
807 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
808 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
809 file, linenum, args[0]);
810 err_code |= ERR_ALERT | ERR_FATAL;
811 goto out;
812 }
813
814 if (global.node)
815 free(global.node);
816
817 global.node = strdup(args[1]);
818 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100819 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100820 if (alertif_too_many_args(1, file, linenum, args, &err_code))
821 goto out;
822 if (global.pidfile != NULL) {
823 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
824 err_code |= ERR_ALERT;
825 goto out;
826 }
827 if (*(args[1]) == 0) {
828 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
829 err_code |= ERR_ALERT | ERR_FATAL;
830 goto out;
831 }
832 global.pidfile = strdup(args[1]);
833 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100834 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100835 int cur_arg = 1;
836 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100837 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100838 if (global.unix_bind.prefix != NULL) {
839 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
840 err_code |= ERR_ALERT;
841 cur_arg += 2;
842 continue;
843 }
844
845 if (*(args[cur_arg+1]) == 0) {
846 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
847 err_code |= ERR_ALERT | ERR_FATAL;
848 goto out;
849 }
850 global.unix_bind.prefix = strdup(args[cur_arg+1]);
851 cur_arg += 2;
852 continue;
853 }
854
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100855 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100856
857 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
858 cur_arg += 2;
859 continue;
860 }
861
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100862 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100863
864 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
865 cur_arg += 2;
866 continue;
867 }
868
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100869 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100870
871 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
872 cur_arg += 2;
873 continue;
874 }
875
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100876 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100877 struct passwd *user;
878
879 user = getpwnam(args[cur_arg + 1]);
880 if (!user) {
881 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
882 file, linenum, args[0], args[cur_arg + 1 ]);
883 err_code |= ERR_ALERT | ERR_FATAL;
884 goto out;
885 }
886
887 global.unix_bind.ux.uid = user->pw_uid;
888 cur_arg += 2;
889 continue;
890 }
891
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100892 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100893 struct group *group;
894
895 group = getgrnam(args[cur_arg + 1]);
896 if (!group) {
897 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
898 file, linenum, args[0], args[cur_arg + 1 ]);
899 err_code |= ERR_ALERT | ERR_FATAL;
900 goto out;
901 }
902
903 global.unix_bind.ux.gid = group->gr_gid;
904 cur_arg += 2;
905 continue;
906 }
907
908 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
909 file, linenum, args[0]);
910 err_code |= ERR_ALERT | ERR_FATAL;
911 goto out;
912 }
913 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100914 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200915 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100916 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
917 err_code |= ERR_ALERT | ERR_FATAL;
918 goto out;
919 }
920 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100921 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100922 char *name;
923
924 if (global.log_send_hostname != NULL) {
925 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
926 err_code |= ERR_ALERT;
927 goto out;
928 }
929
930 if (*(args[1]))
931 name = args[1];
932 else
933 name = hostname;
934
935 free(global.log_send_hostname);
936 global.log_send_hostname = strdup(name);
937 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100938 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 +0100939 if (global.server_state_base != NULL) {
940 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
941 err_code |= ERR_ALERT;
942 goto out;
943 }
944
945 if (!*(args[1])) {
946 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
947 err_code |= ERR_FATAL;
948 goto out;
949 }
950
951 global.server_state_base = strdup(args[1]);
952 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100953 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 +0100954 if (global.server_state_file != NULL) {
955 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
956 err_code |= ERR_ALERT;
957 goto out;
958 }
959
960 if (!*(args[1])) {
961 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
962 err_code |= ERR_FATAL;
963 goto out;
964 }
965
966 global.server_state_file = strdup(args[1]);
967 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100968 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100969 if (alertif_too_many_args(1, file, linenum, args, &err_code))
970 goto out;
971 if (*(args[1]) == 0) {
972 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
973 err_code |= ERR_ALERT | ERR_FATAL;
974 goto out;
975 }
976 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +0200977 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
978 if (b_orig(&global.log_tag) == NULL) {
979 chunk_destroy(&global.log_tag);
980 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
981 err_code |= ERR_ALERT | ERR_FATAL;
982 goto out;
983 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100984 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100985 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100986 if (alertif_too_many_args(1, file, linenum, args, &err_code))
987 goto out;
988 if (global.spread_checks != 0) {
989 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
990 err_code |= ERR_ALERT;
991 goto out;
992 }
993 if (*(args[1]) == 0) {
994 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
995 err_code |= ERR_ALERT | ERR_FATAL;
996 goto out;
997 }
998 global.spread_checks = atol(args[1]);
999 if (global.spread_checks < 0 || global.spread_checks > 50) {
1000 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
1001 err_code |= ERR_ALERT | ERR_FATAL;
1002 }
1003 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001004 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001005 const char *err;
1006 unsigned int val;
1007
1008 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1009 goto out;
1010 if (*(args[1]) == 0) {
1011 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1012 err_code |= ERR_ALERT | ERR_FATAL;
1013 goto out;
1014 }
1015
1016 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001017 if (err == PARSE_TIME_OVER) {
1018 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1019 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001020 err_code |= ERR_ALERT | ERR_FATAL;
1021 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001022 else if (err == PARSE_TIME_UNDER) {
1023 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1024 file, linenum, args[1], args[0]);
1025 err_code |= ERR_ALERT | ERR_FATAL;
1026 }
1027 else if (err) {
1028 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 +01001029 err_code |= ERR_ALERT | ERR_FATAL;
1030 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001031 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001032 }
1033 else if (strcmp(args[0], "cpu-map") == 0) {
1034 /* map a process list to a CPU set */
1035#ifdef USE_CPU_AFFINITY
1036 char *slash;
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001037 unsigned long proc = 0, thread = 0;
1038 int i, j, n, autoinc;
1039 struct hap_cpuset cpus, cpus_copy;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001040
1041 if (!*args[1] || !*args[2]) {
1042 ha_alert("parsing [%s:%d] : %s expects a process number "
1043 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1044 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001045 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001046 err_code |= ERR_ALERT | ERR_FATAL;
1047 goto out;
1048 }
1049
1050 if ((slash = strchr(args[1], '/')) != NULL)
1051 *slash = 0;
1052
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001053 /* note: we silently ignore processes over MAX_PROCS and
1054 * threads over MAX_THREADS so as not to make configurations a
1055 * pain to maintain.
1056 */
1057 if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001058 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
1061 }
1062
1063 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001064 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001065 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1066 err_code |= ERR_ALERT | ERR_FATAL;
1067 goto out;
1068 }
1069 *slash = '/';
1070
1071 if (autoinc && atleast2(proc) && atleast2(thread)) {
1072 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1073 "a process range _AND_ a thread range\n",
1074 file, linenum, args[0], args[1]);
1075 err_code |= ERR_ALERT | ERR_FATAL;
1076 goto out;
1077 }
1078 }
1079
Amaury Denoyellea8082352021-04-06 16:46:15 +02001080 if (parse_cpu_set((const char **)args+2, &cpus, 0, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001081 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1082 err_code |= ERR_ALERT | ERR_FATAL;
1083 goto out;
1084 }
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001085
Willy Tarreau36b9e222018-11-11 15:19:52 +01001086 if (autoinc &&
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001087 my_popcountl(proc) != ha_cpuset_count(&cpus) &&
1088 my_popcountl(thread) != ha_cpuset_count(&cpus)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001089 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1090 "must have the same size to be automatically bound\n",
1091 file, linenum, args[0]);
1092 err_code |= ERR_ALERT | ERR_FATAL;
1093 goto out;
1094 }
1095
Willy Tarreau7764a572019-07-16 15:10:34 +02001096 /* we now have to deal with 3 real cases :
1097 * cpu-map P-Q => mapping for whole processes, numbers P to Q
1098 * cpu-map P-Q/1 => mapping of first thread of processes P to Q
1099 * cpu-map 1/T-U => mapping of threads T to U of process 1
1100 * Otherwise other combinations are silently ignored since nbthread
1101 * and nbproc cannot both be >1 :
1102 * cpu-map P-Q/T => mapping for thread T for processes P to Q.
1103 * Only one of T,Q may be > 1, others ignored.
1104 * cpu-map P/T-U => mapping for threads T to U of process P. Only
1105 * one of P,U may be > 1, others ignored.
1106 */
1107 if (!thread) {
1108 /* mapping for whole processes. E.g. cpu-map 1-4 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001109 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau81492c92019-05-03 09:41:23 +02001110 for (i = n = 0; i < MAX_PROCS; i++) {
1111 /* No mapping for this process */
1112 if (!(proc & (1UL << i)))
1113 continue;
1114
Willy Tarreau36b9e222018-11-11 15:19:52 +01001115 if (!autoinc)
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001116 ha_cpuset_assign(&cpu_map.proc[i], &cpus);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001117 else {
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001118 ha_cpuset_zero(&cpu_map.proc[i]);
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001119 n = ha_cpuset_ffs(&cpus_copy) - 1;
1120 ha_cpuset_clr(&cpus_copy, n);
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001121 ha_cpuset_set(&cpu_map.proc[i], n);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001122 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001123 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001124 } else {
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001125 /* Mapping at the thread level.
1126 * Either proc and/or thread must be 1 and only 1. All
1127 * other combinations are silently ignored.
Willy Tarreau7764a572019-07-16 15:10:34 +02001128 */
1129 if (thread == 0x1) {
1130 /* first thread, iterate on processes. E.g. cpu-map 1-4/1 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001131 struct hap_cpuset *dst;
1132
1133 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001134 for (i = n = 0; i < MAX_PROCS; i++) {
1135 /* No mapping for this process */
1136 if (!(proc & (1UL << i)))
1137 continue;
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001138
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001139 /* For first process, thread[0] is used.
1140 * Use proc_t1[N] for all others
1141 */
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001142 dst = i ? &cpu_map.proc_t1[i] :
1143 &cpu_map.thread[0];
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001144
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001145 if (!autoinc) {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001146 ha_cpuset_assign(dst, &cpus);
Amaury Denoyelleaf02c572021-04-15 16:29:58 +02001147 }
Willy Tarreau7764a572019-07-16 15:10:34 +02001148 else {
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001149 ha_cpuset_zero(dst);
1150 n = ha_cpuset_ffs(&cpus_copy) - 1;
1151 ha_cpuset_clr(&cpus_copy, n);
1152 ha_cpuset_set(dst, n);
Willy Tarreau7764a572019-07-16 15:10:34 +02001153 }
1154 }
1155 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001156
Willy Tarreau7764a572019-07-16 15:10:34 +02001157 if (proc == 0x1) {
1158 /* first process, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001159 ha_cpuset_assign(&cpus_copy, &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001160 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)
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001166 ha_cpuset_assign(&cpu_map.thread[j], &cpus);
Willy Tarreau7764a572019-07-16 15:10:34 +02001167 else {
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001168 ha_cpuset_zero(&cpu_map.thread[j]);
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001169 n = ha_cpuset_ffs(&cpus_copy) - 1;
1170 ha_cpuset_clr(&cpus_copy, n);
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001171 ha_cpuset_set(&cpu_map.thread[j], n);
Willy Tarreau7764a572019-07-16 15:10:34 +02001172 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001173 }
1174 }
Amaury Denoyellea2944ec2021-04-15 18:07:07 +02001175
1176 HA_DIAG_WARNING_COND(proc != 0x1 && thread != 0x1,
1177 "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 +01001178 }
1179#else
1180 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1181 file, linenum, args[0]);
1182 err_code |= ERR_ALERT | ERR_FATAL;
1183 goto out;
1184#endif /* ! USE_CPU_AFFINITY */
1185 }
1186 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1187 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1188 goto out;
1189
1190 if (*(args[2]) == 0) {
1191 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1192 err_code |= ERR_ALERT | ERR_FATAL;
1193 goto out;
1194 }
1195
1196 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1197 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1198 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1199 err_code |= ERR_ALERT | ERR_FATAL;
1200 goto out;
1201 }
1202 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001203 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001204 int arg;
1205
1206 if (*(args[1]) == 0) {
1207 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1208 err_code |= ERR_ALERT | ERR_FATAL;
1209 goto out;
1210 }
1211
1212 for (arg = 1; *args[arg]; arg++) {
1213 if (unsetenv(args[arg]) != 0) {
1214 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1215 err_code |= ERR_ALERT | ERR_FATAL;
1216 goto out;
1217 }
1218 }
1219 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001220 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001221 extern char **environ;
1222 char **env = environ;
1223
1224 /* args contain variable names to keep, one per argument */
1225 while (*env) {
1226 int arg;
1227
1228 /* look for current variable in among all those we want to keep */
1229 for (arg = 1; *args[arg]; arg++) {
1230 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1231 (*env)[strlen(args[arg])] == '=')
1232 break;
1233 }
1234
1235 /* delete this variable */
1236 if (!*args[arg]) {
1237 char *delim = strchr(*env, '=');
1238
1239 if (!delim || delim - *env >= trash.size) {
1240 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1241 err_code |= ERR_ALERT | ERR_FATAL;
1242 goto out;
1243 }
1244
1245 memcpy(trash.area, *env, delim - *env);
1246 trash.area[delim - *env] = 0;
1247
1248 if (unsetenv(trash.area) != 0) {
1249 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1250 err_code |= ERR_ALERT | ERR_FATAL;
1251 goto out;
1252 }
1253 }
1254 else
1255 env++;
1256 }
1257 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001258 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001259 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1260 goto out;
1261 if (kwm == KWM_NO)
1262 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001263 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001264 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001265 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1266 goto out;
1267
1268 if (*(args[1]) == 0) {
1269 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1270 file, linenum, args[0]);
1271 err_code |= ERR_ALERT | ERR_FATAL;
1272 goto out;
1273 }
1274
1275 if (global.localpeer_cmdline != 0) {
1276 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1277 "command line argument.\n", file, linenum, args[0]);
1278 err_code |= ERR_WARN;
1279 goto out;
1280 }
1281
1282 if (cfg_peers) {
1283 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1284 file, linenum, args[0]);
1285 err_code |= ERR_WARN;
1286 goto out;
1287 }
1288
1289 free(localpeer);
1290 if ((localpeer = strdup(args[1])) == NULL) {
1291 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1292 file, linenum, args[0]);
1293 err_code |= ERR_ALERT | ERR_FATAL;
1294 goto out;
1295 }
1296 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1297 }
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +01001298 else if (strcmp(args[0], "numa-cpu-mapping") == 0) {
1299 global.numa_cpu_mapping = (kwm == KWM_NO) ? 0 : 1;
1300 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001301 else {
1302 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001303 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001304 int index;
1305 int rc;
1306
1307 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1308 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1309 if (kwl->kw[index].section != CFG_GLOBAL)
1310 continue;
1311 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001312 if (check_kw_experimental(&kwl->kw[index], file, linenum, &errmsg)) {
Amaury Denoyelle86c1d0f2021-05-07 15:07:21 +02001313 ha_alert("%s\n", errmsg);
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001314 err_code |= ERR_ALERT | ERR_FATAL;
1315 goto out;
1316 }
1317
Willy Tarreau36b9e222018-11-11 15:19:52 +01001318 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1319 if (rc < 0) {
1320 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1321 err_code |= ERR_ALERT | ERR_FATAL;
1322 }
1323 else if (rc > 0) {
1324 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1325 err_code |= ERR_WARN;
1326 goto out;
1327 }
1328 goto out;
1329 }
1330 }
1331 }
1332
Willy Tarreau101df312021-03-15 09:12:41 +01001333 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001334 if (best)
1335 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1336 else
1337 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001338 err_code |= ERR_ALERT | ERR_FATAL;
1339 }
1340
1341 out:
1342 free(errmsg);
1343 return err_code;
1344}
1345