Browse Source

Try to increase file descriptor rlimit if necessary

As the default can be too low, especially on OSX.
miguelfreitas
Pieter Wuille 12 years ago
parent
commit
ba29a5590b
  1. 20
      src/init.cpp
  2. 5
      src/net.cpp
  3. 1
      src/net.h
  4. 23
      src/util.cpp
  5. 1
      src/util.h

20
src/init.cpp

@ -28,6 +28,15 @@ using namespace boost; @@ -28,6 +28,15 @@ using namespace boost;
CWallet* pwalletMain;
CClientUIInterface uiInterface;
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
// accessing block files, don't count towards to fd_set size limit
// anyway.
#define MIN_CORE_FILEDESCRIPTORS 0
#else
#define MIN_CORE_FILEDESCRIPTORS 150
#endif
// Used to pass flags to the Bind() function
enum BindFlags {
BF_NONE = 0,
@ -518,6 +527,16 @@ bool AppInit2(boost::thread_group& threadGroup) @@ -518,6 +527,16 @@ bool AppInit2(boost::thread_group& threadGroup)
SoftSetBoolArg("-rescan", true);
}
// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind"), 1);
nMaxConnections = GetArg("-maxconnections", 125);
nMaxConnections = std::max(std::min(nMaxConnections, FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS), 0);
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available."));
if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug");
@ -594,6 +613,7 @@ bool AppInit2(boost::thread_group& threadGroup) @@ -594,6 +613,7 @@ bool AppInit2(boost::thread_group& threadGroup)
printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
printf("Used data directory %s\n", strDataDir.c_str());
printf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
std::ostringstream strErrors;
if (fDaemon)

5
src/net.cpp

@ -48,6 +48,7 @@ static CNode* pnodeSync = NULL; @@ -48,6 +48,7 @@ static CNode* pnodeSync = NULL;
uint64 nLocalHostNonce = 0;
static std::vector<SOCKET> vhListenSocket;
CAddrMan addrman;
int nMaxConnections = 125;
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
@ -908,7 +909,7 @@ void ThreadSocketHandler() @@ -908,7 +909,7 @@ void ThreadSocketHandler()
if (nErr != WSAEWOULDBLOCK)
printf("socket error accept failed: %d\n", nErr);
}
else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
{
{
LOCK(cs_setservAddNodeAddresses);
@ -1803,7 +1804,7 @@ void StartNode(boost::thread_group& threadGroup) @@ -1803,7 +1804,7 @@ void StartNode(boost::thread_group& threadGroup)
{
if (semOutbound == NULL) {
// initialize semaphore
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
semOutbound = new CSemaphore(nMaxOutbound);
}

1
src/net.h

@ -74,6 +74,7 @@ extern bool fDiscover; @@ -74,6 +74,7 @@ extern bool fDiscover;
extern uint64 nLocalServices;
extern uint64 nLocalHostNonce;
extern CAddrMan addrman;
extern int nMaxConnections;
extern std::vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;

23
src/util.cpp

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/resource.h>
#endif
#include "util.h"
@ -1167,6 +1168,28 @@ bool TruncateFile(FILE *file, unsigned int length) { @@ -1167,6 +1168,28 @@ bool TruncateFile(FILE *file, unsigned int length) {
#endif
}
// this function tries to raise the file descriptor limit to the requested number.
// It returns the actual file descriptor limit (which may be more or less than nMinFD)
int RaiseFileDescriptorLimit(int nMinFD) {
#if defined(WIN32)
return 2048;
#else
struct rlimit limitFD;
if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
if (limitFD.rlim_cur < (rlim_t)nMinFD) {
limitFD.rlim_cur = nMinFD;
if (limitFD.rlim_cur > limitFD.rlim_max)
limitFD.rlim_cur = limitFD.rlim_max;
setrlimit(RLIMIT_NOFILE, &limitFD);
getrlimit(RLIMIT_NOFILE, &limitFD);
}
return limitFD.rlim_cur;
}
return nMinFD; // getrlimit failed, assume it's fine
#endif
}
// this function tries to make a particular range of a file allocated (corresponding to disk space)
// it is advisory, and the range specified in the arguments will never contain live data
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {

1
src/util.h

@ -197,6 +197,7 @@ bool WildcardMatch(const std::string& str, const std::string& mask); @@ -197,6 +197,7 @@ bool WildcardMatch(const std::string& str, const std::string& mask);
void FileCommit(FILE *fileout);
int GetFilesize(FILE* file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
boost::filesystem::path GetDefaultDataDir();

Loading…
Cancel
Save