Skip to content

Commit

Permalink
Try to set sane limits for RLIMIT_NO_FILE
Browse files Browse the repository at this point in the history
E.g. on OSX the default is 256, which isn't exactly compatible with
torrent downloads.

Closes aria2GH-257
  • Loading branch information
nmaier committed Jul 22, 2014
1 parent 70a80b1 commit 8732a24
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
14 changes: 14 additions & 0 deletions doc/manual-src/en/aria2c.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
38 changes: 38 additions & 0 deletions src/Context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions src/OptionHandlerFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/usage_text.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" \
Expand Down

0 comments on commit 8732a24

Please sign in to comment.