------------------------------------------------------------ revno: 10002 revision-id: squid3@treenet.co.nz-20100612114252-aiv5gc1w4umu2kjf parent: squid3@treenet.co.nz-20100612104620-zcj8ixv9aq9ettrt committer: Amos Jeffries branch nick: SQUID_3_1 timestamp: Sat 2010-06-12 23:42:52 +1200 message: 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. ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20100612114252-aiv5gc1w4umu2kjf # target_branch: http://www.squid-cache.org/bzr/squid3/trunk/ # testament_sha1: cc5b7c3179cfdc2aae57cd652ba1aaed4cb0c886 # timestamp: 2010-06-12 11:52:26 +0000 # source_branch: http://www.squid-cache.org/bzr/squid3/branches\ # /SQUID_3_1 # base_revision_id: squid3@treenet.co.nz-20100612104620-\ # zcj8ixv9aq9ettrt # # Begin patch === modified file 'doc/release-notes/release-3.1.html' --- doc/release-notes/release-3.1.html 2010-05-30 13:15:00 +0000 +++ doc/release-notes/release-3.1.html 2010-06-12 11:42:52 +0000 @@ -1000,6 +1000,9 @@

+
max_filedescriptors
+

Ported from 2.7.

+
netdb_filename

@@ -1904,9 +1907,6 @@
 

%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

=== modified file 'doc/release-notes/release-3.1.sgml' --- doc/release-notes/release-3.1.sgml 2010-05-30 13:15:00 +0000 +++ doc/release-notes/release-3.1.sgml 2010-06-12 11:42:52 +0000 @@ -853,6 +853,9 @@ direct client address in the access log. + max_filedescriptors +

Ported from 2.7. + netdb_filename A filename where Squid stores it's netdb state between restarts. @@ -1691,9 +1694,6 @@

%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 === modified file 'src/cf.data.pre' --- src/cf.data.pre 2010-06-12 10:46:20 +0000 +++ src/cf.data.pre 2010-06-12 11:42:52 +0000 @@ -6657,4 +6657,17 @@ 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 === modified file 'src/main.cc' --- src/main.cc 2010-05-29 01:39:35 +0000 +++ src/main.cc 2010-06-12 11:42:52 +0000 @@ -928,7 +928,7 @@ #endif debugs(1, 1, "Process ID " << getpid()); - + setSystemLimits(); debugs(1, 1, "With " << Squid_MaxFD << " file descriptors available"); #ifdef _SQUID_MSWIN_ === modified file 'src/protos.h' --- src/protos.h 2010-05-14 12:40:35 +0000 +++ src/protos.h 2010-06-12 11:42:52 +0000 @@ -571,6 +571,7 @@ 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); === modified file 'src/structs.h' --- src/structs.h 2010-03-06 03:10:13 +0000 +++ src/structs.h 2010-06-12 11:42:52 +0000 @@ -618,6 +618,7 @@ char *accept_filter; int umask; + int max_filedescriptors; #if USE_LOADABLE_MODULES wordlist *loadable_module_names; === modified file 'src/tools.cc' --- src/tools.cc 2009-12-16 00:56:45 +0000 +++ src/tools.cc 2010-06-12 11:42:52 +0000 @@ -869,69 +869,82 @@ 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 */ - - struct rlimit rl; -#if defined(RLIMIT_NOFILE) - - if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { - debugs(50, 0, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); +#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) + struct rlimit rl; + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { + 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) + 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()); + } + } + } + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { + debugs(50, DBG_CRITICAL, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); + } else { + Squid_MaxFD = rl.rlim_cur; + } + +#endif /* HAVE_SETRLIMIT */ +} + +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 (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); - } - } - -#elif defined(RLIMIT_OFILE) - if (getrlimit(RLIMIT_OFILE, &rl) < 0) { - debugs(50, 0, "setrlimit: RLIMIT_NOFILE: " << xstrerror()); - } else { - rl.rlim_cur = Squid_MaxFD; - - if (rl.rlim_cur > rl.rlim_max) - Squid_MaxFD = rl.rlim_cur = rl.rlim_max; - - if (setrlimit(RLIMIT_OFILE, &rl) < 0) { - snprintf(tmp_error_buf, ERROR_BUF_SZ, - "setrlimit: RLIMIT_OFILE: %s", xstrerror()); - fatal_dump(tmp_error_buf); - } - } - -#endif -#else /* HAVE_SETRLIMIT */ - debugs(21, 1, "setMaxFD: Cannot increase: setrlimit() not supported on this system"); - + snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_NOFILE: %s", xstrerror()); + fatal_dump(tmp_error_buf); + } + } #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 @@ 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 */ }