Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ Thank you!
Matthias Pitzl <silamael@coronamundi.de>
Matthieu Herrb <matthieu.herrb@laas.fr>
Max Okumoto <okumoto@ucsd.edu>
Max Schmitt <max@schmitt.mx>
Merik Karman
<mgd@swarm.org>
Michael Buchau <mike@m-buchau.de>
Expand Down
30 changes: 24 additions & 6 deletions src/cf.data.pre
Original file line number Diff line number Diff line change
Expand Up @@ -10681,14 +10681,32 @@ DOC_END
NAME: max_filedescriptors max_filedesc
TYPE: int
DEFAULT: 0
DEFAULT_DOC: Use operating system soft limit set by ulimit.
DEFAULT_DOC: Guess a reasonable value (e.g., use soft limit set by ulimit).
LOC: Config.max_filedescriptors
DOC_START
Set the maximum number of filedescriptors, either below the
operating system default or up to the hard limit.

Remove from squid.conf to inherit the current ulimit soft
limit setting.
Sets the maximum number of file descriptors, up to the hard OS limit (where
supported).

Currently, the explicitly configured value is ignored when `setrlimit(2)` or
`RLIMIT_NOFILE` support was not detected at `./configure` time. A level-1
"WARNING" message is written to cache.log in such cases, but future Squid
versions will fail to start instead.

Currently, if `setrlimit(2)` fails to set the soft and hard limits to the
configured value, a level-0 "ERROR" message is written to cache.log, and
Squid attempts to raise the soft limit to match the hard limit instead. The
resulting soft limit (raised or not) is then used instead of the configured
value. Future Squid versions will fail to start in such cases.

By default, Squid tries to guess a reasonable value (e.g., the current
operating system soft limit set by `ulimit -n` or equivalent). The details
of the guessing algorithm may change. Use this directive to avoid exposure
to those changes and unwanted dependencies on build and runtime environment
states, especially in high-performance deployments that require a large
number of descriptors.

Squid fails to start if `setrlimit(2)` is supported but fails to set a soft
limit to the configured or guessed value.

Note: Changing this requires a restart of Squid. Also
not all I/O types supports large values (eg on Windows).
Expand Down
31 changes: 30 additions & 1 deletion src/tools.cc
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ setMaxFD(void)
struct rlimit rl;
#endif

auto checkLimits = true;

if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
int xerrno = errno;
debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
Expand All @@ -787,13 +789,40 @@ setMaxFD(void)
xerrno = errno;
debugs(50, DBG_CRITICAL, "ERROR: setrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
}
// else: getrlimit() will still return two OS-originated rl.rlim_max limits that must be checked
} else {
// getrlimit() will now return admin-configured numbers, not OS-provided ones
checkLimits = false;
}
}
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
int xerrno = errno;
debugs(50, DBG_CRITICAL, "ERROR: getrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
} else {
Squid_MaxFD = rl.rlim_cur;
// An OS may supply us with huge RLIMIT_NOFILE limits (e.g., the soft
// limit may exceed one billion on Kubernets). We cap these OS-provided
// limits to protect deployments from accidentally or unknowingly
// allocating huge FD-indexed structures (e.g., ~432 GB fd_table on
// Kubernetes). Special deployments that really need more descriptors
// than this cap must set max_filedescriptors accordingly.
const auto defaultCapForMaximumNumberOfFiles = rlim_t(100*1024); // ~42 MB fd_table

// No cap if setrlimit() changed the limits to match max_filedescriptors
// because, in that case, rl.rlim_cur is effectively set by the Squid
// admin (rather than reflecting OS configuration that we do not trust).
if (checkLimits && rl.rlim_cur > defaultCapForMaximumNumberOfFiles) {
debugs(50, DBG_IMPORTANT, "WARNING: OS-provided soft limit (" << rl.rlim_cur << " RLIMIT_NOFILE) " <<
"is too big to use for calculating the maximum number of descriptors Squid may use; " <<
"setting that maximum to " << defaultCapForMaximumNumberOfFiles);
Squid_MaxFD = defaultCapForMaximumNumberOfFiles;
} else {
debugs(50, 3, "Squid_MaxFD was " << Squid_MaxFD << "; now " << rl.rlim_cur << " <= " << rl.rlim_max);
Squid_MaxFD = rl.rlim_cur;
}
// XXX: When checkLimits, take ./configure --with-filedescriptors (if any) into account.
// XXX: rl.rlim_cur is often too small (e.g. 1024). In those cases, use a larger value if rl.rlim_max allows.
// XXX: The new value may make Squid_MaxFD different from SQUID_MAXFD still used by ModEpoll, ModPoll, ipcCreate(), etc.!
// XXX: If this increases Squid_MaxFD, then the new value will violate any defined SQUID_MAXFD_LIMIT.
}

#endif /* HAVE_SETRLIMIT */
Expand Down
Loading