#ifndef _COMMON_DEFAULTS_H
#define _COMMON_DEFAULTS_H
+/* MAX_PROCS defines the highest limit for the global "nbproc" value. It
+ * defaults to the number of bits in a long integer but may be lowered to save
+ * resources on embedded systems.
+ */
+#ifndef MAX_PROCS
+#define MAX_PROCS LONGBITS
+#endif
+
/*
* BUFSIZE defines the size of a read and write buffer. It is the maximum
* amount of bytes which can be stored by the proxy for each stream. However,
struct vars vars; /* list of variables for the process scope. */
#ifdef USE_CPU_AFFINITY
struct {
- unsigned long proc[LONGBITS]; /* list of CPU masks for the 32/64 first processes */
- unsigned long thread[LONGBITS][MAX_THREADS]; /* list of CPU masks for the 32/64 first threads per process */
+ unsigned long proc[MAX_PROCS]; /* list of CPU masks for the 32/64 first processes */
+ unsigned long thread[MAX_PROCS][MAX_THREADS]; /* list of CPU masks for the 32/64 first threads per process */
} cpu_map;
#endif
};
int is_ssl; /* SSL is required for these listeners */
int generate_certs; /* 1 if generate-certificates option is set, else 0 */
unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
- unsigned long bind_thread[LONGBITS]; /* bitmask of threads (per processes) allowed to use these listeners */
+ unsigned long bind_thread[MAX_PROCS]; /* bitmask of threads (per processes) allowed to use these listeners */
struct { /* UNIX socket permissions */
uid_t uid; /* -1 to leave unchanged */
gid_t gid; /* -1 to leave unchanged */
}
global.nbproc = atol(args[1]);
all_proc_mask = nbits(global.nbproc);
- if (global.nbproc < 1 || global.nbproc > LONGBITS) {
+ if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
- file, linenum, args[0], LONGBITS, global.nbproc);
+ file, linenum, args[0], MAX_PROCS, global.nbproc);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
ha_alert("parsing [%s:%d] : %s expects a process number "
" ('all', 'odd', 'even', a number from 1 to %d or a range), "
" followed by a list of CPU ranges with numbers from 0 to %d.\n",
- file, linenum, args[0], LONGBITS, LONGBITS - 1);
+ file, linenum, args[0], MAX_PROCS, LONGBITS - 1);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
if ((slash = strchr(args[1], '/')) != NULL)
*slash = 0;
- if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
+ if (parse_process_number(args[1], &proc, MAX_PROCS, &autoinc, &errmsg)) {
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
goto out;
}
- for (i = n = 0; i < LONGBITS; i++) {
+ for (i = n = 0; i < MAX_PROCS; i++) {
/* No mapping for this process */
if (!(proc & (1UL << i)))
continue;
set = 0;
break;
}
- if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, &errmsg)) {
+ if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, &errmsg)) {
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
mask >>= global.nbthread;
}
- for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
+ for (nbproc = 0; nbproc < MAX_PROCS; nbproc++) {
if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
bind_conf->bind_thread[nbproc] = new_mask;
}
set = 0;
break;
}
- if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, err)) {
+ if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, err)) {
memprintf(err, "'%s %s' : %s", args[0], args[1], *err);
return -1;
}
setvbuf(stdout, NULL, _IONBF, 0);
+ /* this can only safely be done here, though it's optimized away by
+ * the compiler.
+ */
+ if (MAX_PROCS < 1 || MAX_PROCS > LONGBITS) {
+ ha_alert("MAX_PROCS value must be between 1 and %d inclusive; "
+ "HAProxy was built with value %d, please fix it and rebuild.\n",
+ LONGBITS, MAX_PROCS);
+ exit(1);
+ }
+
/* process all initcalls in order of potential dependency */
RUN_INITCALLS(STG_PREPARE);
RUN_INITCALLS(STG_LOCK);
#ifdef USE_CPU_AFFINITY
if (proc < global.nbproc && /* child */
- proc < LONGBITS && /* only the first 32/64 processes may be pinned */
+ proc < MAX_PROCS && /* only the first 32/64 processes may be pinned */
global.cpu_map.proc[proc]) /* only do this if the process has a CPU map */
#ifdef __FreeBSD__
{
if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
*slash = 0;
- if (parse_process_number(args[cur_arg + 1], &proc, LONGBITS, NULL, err)) {
+ if (parse_process_number(args[cur_arg + 1], &proc, MAX_PROCS, NULL, err)) {
memprintf(err, "'%s' : %s", args[cur_arg], *err);
return ERR_ALERT | ERR_FATAL;
}
conf->bind_proc |= proc;
if (thread) {
- for (i = 0; i < LONGBITS; i++)
+ for (i = 0; i < MAX_PROCS; i++)
if (!proc || (proc & (1UL << i)))
conf->bind_thread[i] |= thread;
}