mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-18 11:01:06 +00:00
Merge #9010: Split up AppInit2 into multiple phases, daemonize after datadir lock errors
deec83f init: Get rid of fServer flag (Wladimir J. van der Laan) 16ca0bf init: Try to aquire datadir lock before and after daemonization (Wladimir J. van der Laan) 0cc8b6b init: Split up AppInit2 into multiple phases (Wladimir J. van der Laan)
This commit is contained in:
commit
a143b88dbd
@ -128,6 +128,26 @@ bool AppInit(int argc, char* argv[])
|
|||||||
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
|
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
// -server defaults to true for bitcoind but not for the GUI so do this here
|
||||||
|
SoftSetBoolArg("-server", true);
|
||||||
|
// Set this early so that parameter interactions go to console
|
||||||
|
InitLogging();
|
||||||
|
InitParameterInteraction();
|
||||||
|
if (!AppInitBasicSetup())
|
||||||
|
{
|
||||||
|
// InitError will have been called with detailed error, which ends up on console
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!AppInitParameterInteraction())
|
||||||
|
{
|
||||||
|
// InitError will have been called with detailed error, which ends up on console
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!AppInitSanityChecks())
|
||||||
|
{
|
||||||
|
// InitError will have been called with detailed error, which ends up on console
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
if (GetBoolArg("-daemon", false))
|
if (GetBoolArg("-daemon", false))
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_DAEMON
|
#if HAVE_DECL_DAEMON
|
||||||
@ -143,12 +163,8 @@ bool AppInit(int argc, char* argv[])
|
|||||||
return false;
|
return false;
|
||||||
#endif // HAVE_DECL_DAEMON
|
#endif // HAVE_DECL_DAEMON
|
||||||
}
|
}
|
||||||
SoftSetBoolArg("-server", true);
|
|
||||||
|
|
||||||
// Set this early so that parameter interactions go to console
|
fRet = AppInitMain(threadGroup, scheduler);
|
||||||
InitLogging();
|
|
||||||
InitParameterInteraction();
|
|
||||||
fRet = AppInit2(threadGroup, scheduler);
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
PrintExceptionContinue(&e, "AppInit()");
|
PrintExceptionContinue(&e, "AppInit()");
|
||||||
|
86
src/init.cpp
86
src/init.cpp
@ -780,10 +780,17 @@ void InitLogging()
|
|||||||
LogPrintf("Bitcoin version %s\n", FormatFullVersion());
|
LogPrintf("Bitcoin version %s\n", FormatFullVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize bitcoin.
|
namespace { // Variables internal to initialization process only
|
||||||
* @pre Parameters should be parsed and config file should be read.
|
|
||||||
*/
|
ServiceFlags nRelevantServices = NODE_NETWORK;
|
||||||
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
int nMaxConnections;
|
||||||
|
int nUserMaxConnections;
|
||||||
|
int nFD;
|
||||||
|
ServiceFlags nLocalServices = NODE_NETWORK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppInitBasicSetup()
|
||||||
{
|
{
|
||||||
// ********************************************************* Step 1: setup
|
// ********************************************************* Step 1: setup
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -835,9 +842,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
|
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ********************************************************* Step 2: parameter interactions
|
bool AppInitParameterInteraction()
|
||||||
|
{
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
|
// ********************************************************* Step 2: parameter interactions
|
||||||
|
|
||||||
// also see: InitParameterInteraction()
|
// also see: InitParameterInteraction()
|
||||||
|
|
||||||
@ -849,12 +860,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
|
|
||||||
// Make sure enough file descriptors are available
|
// Make sure enough file descriptors are available
|
||||||
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
|
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
|
||||||
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
|
nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
|
||||||
int nMaxConnections = std::max(nUserMaxConnections, 0);
|
nMaxConnections = std::max(nUserMaxConnections, 0);
|
||||||
|
|
||||||
// Trim requested connection counts, to fit into system limitations
|
// Trim requested connection counts, to fit into system limitations
|
||||||
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
|
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
|
||||||
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
|
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
|
||||||
if (nFD < MIN_CORE_FILEDESCRIPTORS)
|
if (nFD < MIN_CORE_FILEDESCRIPTORS)
|
||||||
return InitError(_("Not enough file descriptors available."));
|
return InitError(_("Not enough file descriptors available."));
|
||||||
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);
|
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);
|
||||||
@ -912,8 +923,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
|
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
|
||||||
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
|
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
|
||||||
|
|
||||||
fServer = GetBoolArg("-server", false);
|
|
||||||
|
|
||||||
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
|
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
|
||||||
int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
|
int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
|
||||||
if (nSignedPruneTarget < 0) {
|
if (nSignedPruneTarget < 0) {
|
||||||
@ -969,9 +978,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
// Option to startup with mocktime set (used for regression testing):
|
// Option to startup with mocktime set (used for regression testing):
|
||||||
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
|
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
|
||||||
|
|
||||||
ServiceFlags nLocalServices = NODE_NETWORK;
|
|
||||||
ServiceFlags nRelevantServices = NODE_NETWORK;
|
|
||||||
|
|
||||||
if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
|
if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
|
||||||
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
|
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
|
||||||
|
|
||||||
@ -1020,17 +1026,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
static bool LockDataDirectory(bool probeOnly)
|
||||||
|
{
|
||||||
// Initialize elliptic curve code
|
|
||||||
ECC_Start();
|
|
||||||
globalVerifyHandle.reset(new ECCVerifyHandle());
|
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
if (!InitSanityCheck())
|
|
||||||
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), _(PACKAGE_NAME)));
|
|
||||||
|
|
||||||
std::string strDataDir = GetDataDir().string();
|
std::string strDataDir = GetDataDir().string();
|
||||||
|
|
||||||
// Make sure only a single Bitcoin process is using the data directory.
|
// Make sure only a single Bitcoin process is using the data directory.
|
||||||
@ -1040,11 +1040,45 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
|
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
|
||||||
if (!lock.try_lock())
|
if (!lock.try_lock()) {
|
||||||
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
|
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
|
||||||
|
}
|
||||||
|
if (probeOnly) {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
} catch(const boost::interprocess::interprocess_exception& e) {
|
} catch(const boost::interprocess::interprocess_exception& e) {
|
||||||
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what()));
|
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what()));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppInitSanityChecks()
|
||||||
|
{
|
||||||
|
// ********************************************************* Step 4: sanity checks
|
||||||
|
|
||||||
|
// Initialize elliptic curve code
|
||||||
|
ECC_Start();
|
||||||
|
globalVerifyHandle.reset(new ECCVerifyHandle());
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (!InitSanityCheck())
|
||||||
|
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), _(PACKAGE_NAME)));
|
||||||
|
|
||||||
|
// Probe the data directory lock to give an early error message, if possible
|
||||||
|
return LockDataDirectory(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
|
{
|
||||||
|
const CChainParams& chainparams = Params();
|
||||||
|
// ********************************************************* Step 4a: application initialization
|
||||||
|
// After daemonization get the data directory lock again and hold on to it until exit
|
||||||
|
// This creates a slight window for a race condition to happen, however this condition is harmless: it
|
||||||
|
// will at most make us exit without printing a message to console.
|
||||||
|
if (!LockDataDirectory(false)) {
|
||||||
|
// Detailed error printed inside LockDataDirectory
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
CreatePidFile(GetPidFile(), getpid());
|
CreatePidFile(GetPidFile(), getpid());
|
||||||
@ -1058,7 +1092,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
if (!fLogTimestamps)
|
if (!fLogTimestamps)
|
||||||
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
|
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
|
||||||
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
||||||
LogPrintf("Using data directory %s\n", strDataDir);
|
LogPrintf("Using data directory %s\n", GetDataDir().string());
|
||||||
LogPrintf("Using config file %s\n", GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
|
LogPrintf("Using config file %s\n", GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
|
||||||
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
||||||
|
|
||||||
@ -1077,7 +1111,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
* that the server is there and will be ready later). Warmup mode will
|
* that the server is there and will be ready later). Warmup mode will
|
||||||
* be disabled when initialisation is finished.
|
* be disabled when initialisation is finished.
|
||||||
*/
|
*/
|
||||||
if (fServer)
|
if (GetBoolArg("-server", false))
|
||||||
{
|
{
|
||||||
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
|
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
|
||||||
if (!AppInitServers(threadGroup))
|
if (!AppInitServers(threadGroup))
|
||||||
|
25
src/init.h
25
src/init.h
@ -25,7 +25,30 @@ void Shutdown();
|
|||||||
void InitLogging();
|
void InitLogging();
|
||||||
//!Parameter interaction: change current parameters depending on various rules
|
//!Parameter interaction: change current parameters depending on various rules
|
||||||
void InitParameterInteraction();
|
void InitParameterInteraction();
|
||||||
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler);
|
|
||||||
|
/** Initialize bitcoin core: Basic context setup.
|
||||||
|
* @note This can be done before daemonization.
|
||||||
|
* @pre Parameters should be parsed and config file should be read.
|
||||||
|
*/
|
||||||
|
bool AppInitBasicSetup();
|
||||||
|
/**
|
||||||
|
* Initialization: parameter interaction.
|
||||||
|
* @note This can be done before daemonization.
|
||||||
|
* @pre Parameters should be parsed and config file should be read, AppInitBasicSetup should have been called.
|
||||||
|
*/
|
||||||
|
bool AppInitParameterInteraction();
|
||||||
|
/**
|
||||||
|
* Initialization sanity checks: ecc init, sanity checks, dir lock.
|
||||||
|
* @note This can be done before daemonization.
|
||||||
|
* @pre Parameters should be parsed and config file should be read, AppInitParameterInteraction should have been called.
|
||||||
|
*/
|
||||||
|
bool AppInitSanityChecks();
|
||||||
|
/**
|
||||||
|
* Bitcoin core main initialization.
|
||||||
|
* @note This should only be done after daemonization.
|
||||||
|
* @pre Parameters should be parsed and config file should be read, AppInitSanityChecks should have been called.
|
||||||
|
*/
|
||||||
|
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler);
|
||||||
|
|
||||||
/** The help message mode determines what help message to show */
|
/** The help message mode determines what help message to show */
|
||||||
enum HelpMessageMode {
|
enum HelpMessageMode {
|
||||||
|
@ -268,7 +268,22 @@ void BitcoinCore::initialize()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
qDebug() << __func__ << ": Running AppInit2 in thread";
|
qDebug() << __func__ << ": Running AppInit2 in thread";
|
||||||
int rv = AppInit2(threadGroup, scheduler);
|
if (!AppInitBasicSetup())
|
||||||
|
{
|
||||||
|
Q_EMIT initializeResult(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!AppInitParameterInteraction())
|
||||||
|
{
|
||||||
|
Q_EMIT initializeResult(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!AppInitSanityChecks())
|
||||||
|
{
|
||||||
|
Q_EMIT initializeResult(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int rv = AppInitMain(threadGroup, scheduler);
|
||||||
Q_EMIT initializeResult(rv);
|
Q_EMIT initializeResult(rv);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
handleRunawayException(&e);
|
handleRunawayException(&e);
|
||||||
|
@ -107,7 +107,6 @@ map<string, vector<string> > mapMultiArgs;
|
|||||||
bool fDebug = false;
|
bool fDebug = false;
|
||||||
bool fPrintToConsole = false;
|
bool fPrintToConsole = false;
|
||||||
bool fPrintToDebugLog = true;
|
bool fPrintToDebugLog = true;
|
||||||
bool fServer = false;
|
|
||||||
string strMiscWarning;
|
string strMiscWarning;
|
||||||
bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS;
|
bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS;
|
||||||
bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
|
bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
|
||||||
|
@ -46,7 +46,6 @@ extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
|
|||||||
extern bool fDebug;
|
extern bool fDebug;
|
||||||
extern bool fPrintToConsole;
|
extern bool fPrintToConsole;
|
||||||
extern bool fPrintToDebugLog;
|
extern bool fPrintToDebugLog;
|
||||||
extern bool fServer;
|
|
||||||
extern std::string strMiscWarning;
|
extern std::string strMiscWarning;
|
||||||
extern bool fLogTimestamps;
|
extern bool fLogTimestamps;
|
||||||
extern bool fLogTimeMicros;
|
extern bool fLogTimeMicros;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user