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;
CWallet* pwalletMain; CWallet* pwalletMain;
CClientUIInterface uiInterface; 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 // Used to pass flags to the Bind() function
enum BindFlags { enum BindFlags {
BF_NONE = 0, BF_NONE = 0,
@ -518,6 +527,16 @@ bool AppInit2(boost::thread_group& threadGroup)
SoftSetBoolArg("-rescan", true); 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 // ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug"); fDebug = GetBoolArg("-debug");
@ -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("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("Default data directory %s\n", GetDefaultDataDir().string().c_str());
printf("Used data directory %s\n", strDataDir.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; std::ostringstream strErrors;
if (fDaemon) if (fDaemon)

5
src/net.cpp

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

1
src/net.h

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

23
src/util.cpp

@ -10,6 +10,7 @@
#endif #endif
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/resource.h>
#endif #endif
#include "util.h" #include "util.h"
@ -1167,6 +1168,28 @@ bool TruncateFile(FILE *file, unsigned int length) {
#endif #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) // 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 // 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) { 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);
void FileCommit(FILE *fileout); void FileCommit(FILE *fileout);
int GetFilesize(FILE* file); int GetFilesize(FILE* file);
bool TruncateFile(FILE *file, unsigned int length); bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
boost::filesystem::path GetDefaultDataDir(); boost::filesystem::path GetDefaultDataDir();

Loading…
Cancel
Save