aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-10-25 12:03:22 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-11-29 12:47:13 +0100
commit16ca0bfd2848424de7deae307283d9eb9de8a978 (patch)
treed33a4bcfc19a83aeb538085e5aad92f45687ed2c /src/init.cpp
parent0cc8b6bc44bea29e24fa4e13d8a9bbe4f1483680 (diff)
init: Try to aquire datadir lock before and after daemonization
Before daemonization, just probe the data directory lock and print an early error message if possible. 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. $ src/bitcoind -testnet -daemon Bitcoin server starting $ src/bitcoind -testnet -daemon Error: Cannot obtain a lock on data directory /home/orion/.bitcoin/testnet3. Bitcoin Core is probably already running.
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 4f435dc7cf..b70e6e9158 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1039,18 +1039,8 @@ bool AppInitParameterInteraction()
return true;
}
-bool AppInitSanityChecks()
+static bool LockDataDirectory(bool probeOnly)
{
- // ********************************************************* 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)));
-
std::string strDataDir = GetDataDir().string();
// Make sure only a single Bitcoin process is using the data directory.
@@ -1063,16 +1053,42 @@ bool AppInitSanityChecks()
if (!lock.try_lock()) {
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) {
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
CreatePidFile(GetPidFile(), getpid());