From: Amos Jeffries Date: Sat, 12 Jun 2010 11:42:52 +0000 (+1200) Subject: Author: Henrik Nordstrom X-Git-Tag: SQUID_3_1_5~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4006ee75b225c47c01b93123d676b06300a506fa;p=thirdparty%2Fsquid.git Author: Henrik Nordstrom Port from 2.7: max_filedescriptor config option Since Squid no longer really has any hardcoded filedescriptor limitations it makes sense to have a squid.conf directive allowing the number of filedescriptors to be tuned runtime. Default if unset is to obey whatever ulimit settings as before. * setMaxFD: figures out what to we can use for Squid_MaxFD * setSystemLimits: Configures the system limitations to match our expectations which might be lower than what setMaxFD finds if the comm loop has additional restrictions * Restrict limited select() I/O loop below FD_SETSIZE. AYJ: Henrik informs that loops using fd_set() (select and win32-select) must be kept below FD_SETSIZE or they can hang Squid or cause out-of-bounds memory errors. NP: Squid-2 does not appear to limit select() like this. May need fixing too. --- diff --git a/doc/release-notes/release-3.1.html b/doc/release-notes/release-3.1.html index 720600c078..c553f07d9a 100644 --- a/doc/release-notes/release-3.1.html +++ b/doc/release-notes/release-3.1.html @@ -1000,6 +1000,9 @@ Default: ON

+
max_filedescriptors
+

Ported from 2.7.

+
netdb_filename

@@ -1904,9 +1907,6 @@ Use --without-pthreads to disable, but only if you really have to.

%oa tag not yet ported from 2.7

%sn tag not yet ported from 2.7

-
max_filedescriptors
-

Not yet ported from 2.7

-
max_stale

Not yet ported from 2.7

diff --git a/doc/release-notes/release-3.1.sgml b/doc/release-notes/release-3.1.sgml index c772aaa5af..5a9a946711 100644 --- a/doc/release-notes/release-3.1.sgml +++ b/doc/release-notes/release-3.1.sgml @@ -853,6 +853,9 @@ logformat icap_squid %ts.%03tu %6icap::tr %>a %icap::to/%03icap::Hs %icap:: + max_filedescriptors +

Ported from 2.7. + netdb_filename A filename where Squid stores it's netdb state between restarts. @@ -1691,9 +1694,6 @@ This section gives an account of those changes in three categories:

%oa tag not yet ported from 2.7

%sn tag not yet ported from 2.7 - max_filedescriptors -

Not yet ported from 2.7 - max_stale

Not yet ported from 2.7 diff --git a/src/cf.data.pre b/src/cf.data.pre index 3a914cb0b1..573cefeeeb 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -6657,4 +6657,17 @@ DOC_START Note: after changing this, Squid service must be restarted. DOC_END +NAME: max_filedescriptors max_filedesc +TYPE: int +DEFAULT: 0 +LOC: Config.max_filedescriptors +DOC_START + The maximum number of filedescriptors supported. + + The default "0" means Squid inherits the current ulimit setting. + + Note: Changing this requires a restart of Squid. Also + not all comm loops supports large values. +DOC_END + EOF diff --git a/src/main.cc b/src/main.cc index 47d6a261f6..3fe99cce8e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -928,7 +928,7 @@ mainInitialize(void) #endif debugs(1, 1, "Process ID " << getpid()); - + setSystemLimits(); debugs(1, 1, "With " << Squid_MaxFD << " file descriptors available"); #ifdef _SQUID_MSWIN_ diff --git a/src/protos.h b/src/protos.h index 4a4a2c5886..acb13ceff1 100644 --- a/src/protos.h +++ b/src/protos.h @@ -571,6 +571,7 @@ SQUIDCEXTERN void no_suid(void); SQUIDCEXTERN void writePidFile(void); SQUIDCEXTERN void setSocketShutdownLifetimes(int); SQUIDCEXTERN void setMaxFD(void); +SQUIDCEXTERN void setSystemLimits(void); SQUIDCEXTERN void squid_signal(int sig, SIGHDLR *, int flags); SQUIDCEXTERN pid_t readPidFile(void); SQUIDCEXTERN void keepCapabilities(void); diff --git a/src/structs.h b/src/structs.h index a2ce6fb67e..0f88b8b76c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -618,6 +618,7 @@ struct SquidConfig { char *accept_filter; int umask; + int max_filedescriptors; #if USE_LOADABLE_MODULES wordlist *loadable_module_names; diff --git a/src/tools.cc b/src/tools.cc index 63ee61072c..d9e4dbff0a 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -869,69 +869,82 @@ readPidFile(void) return pid; } +/* A little piece of glue for odd systems */ +#ifndef RLIMIT_NOFILE +#ifdef RLIMIT_OFILE +#define RLIMIT_NOFILE RLIMIT_OFILE +#endif +#endif +/** Figure out the number of supported filedescriptors */ void setMaxFD(void) { -#if HAVE_SETRLIMIT - /* try to use as many file descriptors as possible */ - /* System V uses RLIMIT_NOFILE and BSD uses RLIMIT_OFILE */ - +#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) struct rlimit rl; -#if defined(RLIMIT_NOFILE) - if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { - debugs(50, 0, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); - } else { - rl.rlim_cur = Squid_MaxFD; - + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + } else if (Config.max_filedescriptors > 0) { +#if USE_SELECT || USE_SELECT_WIN32 + /* select() breaks if this gets set too big */ + if (Config.max_filedescriptors > FD_SETSIZE) + rl.rlim_cur = FD_SETSIZE; + else +#endif + rl.rlim_cur = Config.max_filedescriptors; if (rl.rlim_cur > rl.rlim_max) - Squid_MaxFD = rl.rlim_cur = rl.rlim_max; - - if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { - snprintf(tmp_error_buf, ERROR_BUF_SZ, - "setrlimit: RLIMIT_NOFILE: %s", xstrerror()); - fatal_dump(tmp_error_buf); + rl.rlim_max = rl.rlim_cur; + if (setrlimit(RLIMIT_NOFILE, &rl)) { + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + getrlimit(RLIMIT_NOFILE, &rl); + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rl)) { + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + } } } - -#elif defined(RLIMIT_OFILE) - if (getrlimit(RLIMIT_OFILE, &rl) < 0) { - debugs(50, 0, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); } else { - rl.rlim_cur = Squid_MaxFD; + Squid_MaxFD = rl.rlim_cur; + } - if (rl.rlim_cur > rl.rlim_max) - Squid_MaxFD = rl.rlim_cur = rl.rlim_max; +#endif /* HAVE_SETRLIMIT */ +} - if (setrlimit(RLIMIT_OFILE, &rl) < 0) { - snprintf(tmp_error_buf, ERROR_BUF_SZ, - "setrlimit: RLIMIT_OFILE: %s", xstrerror()); +void +setSystemLimits(void) +{ +#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !defined(_SQUID_CYGWIN_) + /* limit system filedescriptors to our own limit */ + struct rlimit rl; + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + } else { + rl.rlim_cur = Squid_MaxFD; + if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { + snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_NOFILE: %s", xstrerror()); fatal_dump(tmp_error_buf); } } - -#endif -#else /* HAVE_SETRLIMIT */ - debugs(21, 1, "setMaxFD: Cannot increase: setrlimit() not supported on this system"); - #endif /* HAVE_SETRLIMIT */ #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) - if (getrlimit(RLIMIT_DATA, &rl) < 0) { - debugs(50, 0, "getrlimit: RLIMIT_DATA: " << xstrerror()); + debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_DATA: " << xstrerror()); } else if (rl.rlim_max > rl.rlim_cur) { rl.rlim_cur = rl.rlim_max; /* set it to the max */ if (setrlimit(RLIMIT_DATA, &rl) < 0) { - snprintf(tmp_error_buf, ERROR_BUF_SZ, - "setrlimit: RLIMIT_DATA: %s", xstrerror()); + snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_DATA: %s", xstrerror()); fatal_dump(tmp_error_buf); } } - #endif /* RLIMIT_DATA */ + if (Config.max_filedescriptors > Squid_MaxFD) { + debugs(50, DBG_IMPORTANT, "NOTICE: Could not increase the number of filedescriptors"); + } + #if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) if (getrlimit(RLIMIT_VMEM, &rl) < 0) { debugs(50, 0, "getrlimit: RLIMIT_VMEM: " << xstrerror()); @@ -939,12 +952,10 @@ setMaxFD(void) rl.rlim_cur = rl.rlim_max; /* set it to the max */ if (setrlimit(RLIMIT_VMEM, &rl) < 0) { - snprintf(tmp_error_buf, ERROR_BUF_SZ, - "setrlimit: RLIMIT_VMEM: %s", xstrerror()); + snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_VMEM: %s", xstrerror()); fatal_dump(tmp_error_buf); } } - #endif /* RLIMIT_VMEM */ }