Try to set sane limits for RLIMIT_NO_FILE

E.g. on OSX the default is 256, which isn't exactly compatible with
torrent downloads.

Closes GH-257
pull/257/merge
Nils Maier 2014-07-15 08:16:13 +02:00
parent 70a80b1455
commit 8732a24433
7 changed files with 85 additions and 0 deletions

View File

@ -646,6 +646,7 @@ AC_CHECK_HEADERS([argz.h \
strings.h \
sys/ioctl.h \
sys/param.h \
sys/resource.h \
sys/signal.h \
sys/socket.h \
sys/time.h \

View File

@ -1186,6 +1186,20 @@ Advanced Options
you take commonly used values from RFC, network vendors'
documentation, Wikipedia or any other source, use them as they are.
.. option:: --rlimit-nofile=NUM
Set the soft limit of open file descriptors.
This open will only have effect when:
a) The system supports it (posix)
b) The limit does not exceed the hard limit.
c) The specified limit is larger than the current soft limit.
This is equivalent to setting nofile via ulimit,
except that it will never decrease the limit.
This option is only available on systems supporting the rlimit API.
.. option:: --enable-color[=true|false]
Enable color output for a terminal.

View File

@ -37,6 +37,11 @@
#include <unistd.h>
#include <getopt.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif // HAVE_SYS_RESOURCE_H
#include <numeric>
#include <vector>
#include <iostream>
@ -180,6 +185,39 @@ Context::Context(bool standalone,
A2_LOG_INFO(usedLibs());
A2_LOG_INFO(MSG_LOGGING_STARTED);
#if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_NOFILE)
rlimit r = { 0, 0 };
if (getrlimit(RLIMIT_NOFILE, &r) >= 0 && r.rlim_cur != RLIM_INFINITY) {
// Thanks portability, for making it easy :p
auto rlim_new = r.rlim_cur; // So we get the right type for free.
if (r.rlim_cur != RLIM_INFINITY) {
rlim_new = op->getAsInt(PREF_RLIMIT_NOFILE);
rlim_new = std::max(r.rlim_cur, rlim_new);
if (r.rlim_max != RLIM_INFINITY) {
rlim_new = std::min(r.rlim_max, rlim_new);
}
}
if (rlim_new != r.rlim_cur) {
if (setrlimit(RLIMIT_NOFILE, &r) != 0) {
int errNum = errno;
A2_LOG_WARN(fmt("Failed to set rlimit NO_FILE from %" PRIu64 " to "
"%" PRIu64 ": %s",
(uint64_t)r.rlim_cur, (uint64_t)rlim_new,
util::safeStrerror(errNum).c_str()));
}
else {
A2_LOG_DEBUG(fmt("Set rlimit NO_FILE from %" PRIu64 " to %" PRIu64,
(uint64_t)r.rlim_cur, (uint64_t)rlim_new));
}
}
else {
rlim_new = op->getAsInt(PREF_RLIMIT_NOFILE);
A2_LOG_DEBUG(fmt("Not setting rlimit NO_FILE: %" PRIu64 " >= %" PRIu64,
(uint64_t)r.rlim_cur, (uint64_t)rlim_new));
}
}
#endif // defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_NOFILE)
if(op->getAsBool(PREF_DISABLE_IPV6)) {
SocketCore::setProtocolFamily(AF_INET);
// Get rid of AI_ADDRCONFIG. It causes name resolution error

View File

@ -755,6 +755,25 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
#ifdef HAVE_SYS_RESOURCE_H
{
OptionHandler* op(new NumberOptionHandler
(PREF_RLIMIT_NOFILE,
TEXT_RLIMIT_NOFILE,
// Somewhat sane default that most *nix use.
// Some other *nix, like OSX, have insane defaults like
// 256, hence better *not* get the default value from
// getrlimit().
"1024",
// 1 should not be a problem in practise, since the code
// will only adjust if the specified value > the current
// soft limit.
// And sane systems have a default soft limit > 1.
1));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
#endif // HAVE_SYS_RESOURCE_H
{
OptionHandler* op(new BooleanOptionHandler
(PREF_SELECT_LEAST_USED_HOST,

View File

@ -365,6 +365,8 @@ PrefPtr PREF_RPC_SECRET = makePref("rpc-secret");
PrefPtr PREF_DSCP = makePref("dscp");
// values: true | false
PrefPtr PREF_PAUSE_METADATA = makePref("pause-metadata");
// values: 1*digit
PrefPtr PREF_RLIMIT_NOFILE = makePref("rlimit-nofile");
/**
* FTP related preferences

View File

@ -302,6 +302,8 @@ extern PrefPtr PREF_RPC_SECRET;
extern PrefPtr PREF_DSCP;
// values: true | false
extern PrefPtr PREF_PAUSE_METADATA;
// values: 1*digit
extern PrefPtr PREF_RLIMIT_NOFILE;
/**
* FTP related preferences

View File

@ -980,6 +980,15 @@
" commonly used values from RFC, network vendors'\n" \
" documentation, Wikipedia or any other source,\n" \
" use them as they are.")
#define TEXT_RLIMIT_NOFILE \
_(" --rlimit-nofile=NUM Set the soft limit of open file descriptors.\n" \
" This open will only have effect when:\n" \
" a) The system supports it (posix)\n" \
" b) The limit does not exceed the hard limit.\n" \
" c) The specified limit is larger than the\n" \
" current soft limit.\n" \
" This is equivalent to setting nofile via ulimit,\n" \
" except that it will never decrease the limit.")
#define TEXT_PAUSE_METADATA \
_(" --pause-metadata[=true|false]\n" \
" Pause downloads created as a result of metadata\n" \