15 Commits

Author SHA1 Message Date
Willy Tarreau
4cbff2cad9 MINOR: limits: display the computed maxconn using ha_notice()
The computed maxconn was only displayed in verbose or debug modes. This
is too bad because lots of users just don't know what they're starting
with and can be trapped when an environment changes. Let's use ha_notice()
instead of a conditional fprintf() so that it gets displayed right after
the other startup messages, hoping that users will get used to seeing it
and more easily spot anomalies. See github issue #3191 for more context.
2025-11-20 18:38:09 +01:00
Willy Tarreau
8438ca273f MINOR: limits: explain a bit better what to do when fd limits are exceeded
As shown in github issue #3191, the error message shown when FD limits
are exceeded is not very useful as-is, since the current hard limit is
not displayed, and no suggestion is made about what to change in the
config. Let's explain about maxconn/ulimit-n/fd-hard-limit, suggest
dropping them or setting them to a context-based value at roughly 49%
of the current limit minus the known used FDs for listeners and checks.
This allows common "large" hard limits to report mostly round maxconns.
Example:

  [ALERT]    (25330) : [haproxy.main()] Cannot raise FD limit to 4001020,
  current limit is 1024 and hard limit is 4096. You may prefer to let
  HAProxy adjust the limit by itself; for this, please just drop any
  'maxconn' and 'ulimit-n' from the global section, and possibly add
  'fd-hard-limit' lower than this hard limit. You may also force a new
  'maxconn' value that is a bit lower than half of the hard limit minus
  listeners and checks. This results in roughly 1500 here.
2025-11-20 08:44:52 +01:00
Willy Tarreau
91d4f4f618 MINOR: limits: keep a copy of the rough estimate of needed FDs in global struct
It's always a pain to guess the number of FDs that can be needed by
listeners, checks, threads, pollers etc. We have this estimate in
global.maxsock before calling set_global_maxconn(), but we lose it
the line after. Let's copy it into global.est_fd_usage and keep it.
This will be helpful to try to provide more accurate suggestions for
maxconn.
2025-11-20 08:44:52 +01:00
Ilia Shipitsin
27a6353ceb CLEANUP: assorted typo fixes in the code, commits and doc 2025-04-03 11:37:25 +02:00
Valentine Krasnobaeva
6986e3f41f MINOR: limits: fix check_if_maxsock_permitted description
Fix typo in check_if_maxsock_permitted() description.
2025-03-18 17:38:04 +01:00
Valentine Krasnobaeva
060f441199 BUG/MINOR: limits: compute_ideal_maxconn: don't cap remain if fd_hard_limit=0
'global.fd_hard_limit' stays uninitialized, if haproxy is started with -m
(global.rlimit_memmax). 'remain' is the MAX between soft and hard process fd
limits. It will be always bigger than 'global.fd_hard_limit' (0) in this case.

So, if we reassign 'remain' to the 'global.fd_hard_limit' unconditionally,
calculated then 'maxconn' will be even negative and the DEFAULT_MAXCONN (100)
will be set as the 'ideal_maxconn'.

During the 'global.maxconn' calculations in set_global_maxconn(), if the
provided 'global.rlimit_memmax' is quite big, system will refuse to calculate
based on its 'global.maxconn' and we will do a fallback to the 'ideal_maxconn',
which is 100.

Same problem for the configs with SSL frontends and backends.

This fixes the issue #2899.

This should be backported to v3.1.0.
2025-03-18 17:37:33 +01:00
Valentine Krasnobaeva
fbc534a6fa REORG: startup: move nofile limit checks in limits.c
Let's encapsulate the code, which checks the applied nofile limit into
a separate helper check_nofile_lim_and_prealloc_fd(). Let's keep in this new
function scope the block, which tries to create a copy of FD with the highest
number, if prealloc-fd is set in the configuration.
2024-12-16 10:44:01 +01:00
Valentine Krasnobaeva
14f5e00d38 REORG: startup: move code that applies limits to limits.c
In step_init_3() we try to apply provided or calculated earlier haproxy
maxsock and memmax limits.

Let's encapsulate these code blocks in dedicated functions:
apply_nofile_limit() and apply_memory_limit() and let's move them into
limits.c. Limits.c gathers now all the logic for calculating and setting
system limits in dependency of the provided configuration.
2024-12-16 10:44:01 +01:00
Valentine Krasnobaeva
1332e9b58d REORG: startup: move global.maxconn calculations in limits.c
Let's encapsulate the code, which calculates global.maxconn and
global.maxsslconn into a dedicated function set_global_maxconn() and let's
move this function in limits.c. In limits.c we keep helpers to calculate and
check haproxy internal limits, based on the system nofile and memory limits.
2024-12-16 10:44:01 +01:00
Valentine Krasnobaeva
665dde6481 MINOR: debug: use LIM2A to show limits
It is more handy to use LIM2A in debug_parse_cli_show_dev(), as it allows to
show a custom string ("unlimited"), if a given limit value equals to 0.

normalize_rlim() handler is needed to convert properly RLIM_INFINITY to zero,
with the respect of type sizes, as rlim_t is always 4 bytes on 32bit and
64bit arch.
2024-07-16 14:04:41 +02:00
Valentine Krasnobaeva
3a0b44b122 MINOR: limits: add is_any_limit_configured
Let's encapsulate the check of all supported for now process internal limits in
a separate function. This will help in cases, when we need to simply check if
we have even only one limit set in the configuration file. It's important, as
the default value for a one limit (fd-hard-limits, for example) sometimes must
not affect the computation of the others.
2024-07-10 18:05:48 +02:00
Valentine Krasnobaeva
1f8addfdc2 REORG: haproxy: move limits handlers to limits
This patch moves handlers to compute process related limits in 'limits'
compilation unit.
2024-07-10 18:05:48 +02:00
Valentine Krasnobaeva
b8dc783eb9 REORG: global: move rlim_fd_*_at_boot in limits
Let's move in 'limits' compilation unit global variables to keep the initial
process fd limits.
2024-07-10 18:05:48 +02:00
Valentine Krasnobaeva
3759674047 REORG: fd: move raise_rlim_nofile to limits
Let's move raise_rlim_nofile() from 'fd' compilation unit to 'limits', as it
wraps setrlimit to change process RLIMIT_NOFILE.
2024-07-10 18:05:48 +02:00
Valentine Krasnobaeva
1517bcb5e3 MINOR: limits: prepare to keep limits in one place
The code which gets, sets and checks initial and current fd limits and process
related limits (maxconn, maxsock, ulimit-n, fd-hard-limit) is spread around
different functions in haproxy.c and in fd.c. Let's group it together in
dedicated limits.c and limits.h.

This patch is done in order to prepare the moving of limits-related functions
from different places to the new 'limits' compilation unit. It helps to keep
clean the next patch, which will do only the move without any additional
modifications.

Such detailed split is needed in order to be sure not to break accidentally
limits logic and in order to be able to compile each commit separately in case
of git-bisect.
2024-07-10 18:05:48 +02:00