Try to increase file descriptor rlimit if necessary
As the default can be too low, especially on OSX.
This commit is contained in:
parent
33029bcedd
commit
ba29a5590b
5 changed files with 48 additions and 2 deletions
20
src/init.cpp
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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
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) {
|
||||||
|
|
|
@ -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…
Reference in a new issue