diff --git a/doc/configuration.txt b/doc/configuration.txt index f8d44cbeb..5f8474adf 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1107,6 +1107,7 @@ The following keywords are supported in the "global" section : - pidfile - pp2-never-send-local - presetenv + - prealloc-fd - resetenv - set-dumpable - set-var @@ -2084,6 +2085,12 @@ presetenv in the configuration file sees the new value. See also "setenv", "resetenv", and "unsetenv". +prealloc-fd + Performs a one-time open of the maximum file descriptor which results in a + pre-allocation of the kernel's data structures. This prevents short pauses + when nbthread>1 and HAProxy opens a file descriptor which requires the kernel + to expand its data structures. + resetenv [ ...] Removes all environment variables except the ones specified in argument. It allows to use a clean controlled environment before setting new values with diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index e7d02fe2f..0bcfa577a 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -188,6 +188,7 @@ struct global { } unix_bind; struct proxy *cli_fe; /* the frontend holding the stats settings */ int numa_cpu_mapping; + int prealloc_fd; int cfg_curr_line; /* line number currently being parsed */ const char *cfg_curr_file; /* config file currently being parsed or NULL */ char *cfg_curr_section; /* config section name currently being parsed or NULL */ diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index cc643f46e..30334ba13 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -1357,3 +1357,21 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) return err_code; } +static int cfg_parse_prealloc_fd(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + if (too_many_args(0, args, err, NULL)) + return -1; + + global.prealloc_fd = 1; + + return 0; +} + +static struct cfg_kw_list cfg_kws = {ILH, { + { CFG_GLOBAL, "prealloc-fd", cfg_parse_prealloc_fd }, + { 0, NULL, NULL }, +}}; + +INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws); diff --git a/src/haproxy.c b/src/haproxy.c index 0eb78d857..040564701 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3522,6 +3522,14 @@ int main(int argc, char **argv) global.maxsock); } + if (global.prealloc_fd && fcntl((int)limit.rlim_cur - 1, F_GETFD) == -1) { + if (dup2(0, (int)limit.rlim_cur - 1) == -1) + ha_warning("[%s.main()] Unable to preallocate file descriptor %lu : %s", + argv[0], limit.rlim_cur-1, strerror(errno)); + else + close((int)limit.rlim_cur - 1); + } + /* update the ready date a last time to also account for final setup time */ clock_update_date(0, 1); clock_adjust_now_offset();