From 878e0d45a5d1469965d456a5d8a436b45ac59c3a Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 3 Jul 2017 15:30:52 +1000 Subject: [PATCH 1/2] Always allow extra file descriptors when setting the connection maximum When setting the maximum number of connections allowed by the OS, always allow some extra file descriptors for other files. Fixes bug 22797; bugfix on 0.2.0.10-alpha. --- changes/bug22797 | 4 ++++ src/common/compat.c | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 changes/bug22797 diff --git a/changes/bug22797 b/changes/bug22797 new file mode 100644 index 000000000..619baaa40 --- /dev/null +++ b/changes/bug22797 @@ -0,0 +1,4 @@ + o Minor bugfixes (file limits): + - When setting the maximum number of connections allowed by the OS, + always allow some extra file descriptors for other files. + Fixes bug 22797; bugfix on 0.2.0.10-alpha. diff --git a/src/common/compat.c b/src/common/compat.c index e25ecc462..eee52ad34 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1568,19 +1568,24 @@ set_max_file_descriptors(rlim_t limit, int *max_out) if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { int bad = 1; #ifdef OPEN_MAX - if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) { + uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER; + if (errno == EINVAL && try_limit < rlim.rlim_cur) { /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is * full of nasty lies. I'm looking at you, OSX 10.5.... */ - rlim.rlim_cur = OPEN_MAX; + rlim.rlim_cur = try_limit; if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) { if (rlim.rlim_cur < (rlim_t)limit) { log_warn(LD_CONFIG, "We are limited to %lu file descriptors by " - "OPEN_MAX, and ConnLimit is %lu. Changing ConnLimit; sorry.", - (unsigned long)OPEN_MAX, (unsigned long)limit); + "OPEN_MAX (%lu), and ConnLimit is %lu. Changing " + "ConnLimit; sorry.", + (unsigned long)try_limit, (unsigned long)OPEN_MAX, + (unsigned long)limit); } else { - log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); " - "Apparently, %lu was too high and rlimit lied to us.", - (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max); + log_info(LD_CONFIG, "Dropped connection limit to %lu based on " + "OPEN_MAX (%lu); Apparently, %lu was too high and rlimit " + "lied to us.", + (unsigned long)try_limit, (unsigned long)OPEN_MAX, + (unsigned long)rlim.rlim_max); } bad = 0; } From 6a49e3360bcb30b267da4a47af749bd4571ee72d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 5 Jul 2017 15:56:57 -0400 Subject: [PATCH 2/2] Fix mixed-sign comparison warning in fix for 22797. --- src/common/compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/compat.c b/src/common/compat.c index 3ebcfad14..e16dfb1d2 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1719,7 +1719,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out) int bad = 1; #ifdef OPEN_MAX uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER; - if (errno == EINVAL && try_limit < rlim.rlim_cur) { + if (errno == EINVAL && try_limit < (uint64_t) rlim.rlim_cur) { /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is * full of nasty lies. I'm looking at you, OSX 10.5.... */ rlim.rlim_cur = try_limit;