diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2019-02-21 09:06:05 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2019-02-21 09:23:10 +0100 |
commit | 3e1ca1348cbd0d61143585e56eb75950c6028086 (patch) | |
tree | 1d77b32f6ca3ef8548bbe394097fd696d0b9460b | |
parent | f9775a865597b3cc926ba3375fa692516c7415be (diff) | |
parent | 3782075a5fd4ad0c15a6119e8cdaf136898f679e (diff) |
Merge #15278: Improve PID file error handling
3782075a5fd4ad0c15a6119e8cdaf136898f679e Move all PID file stuff to init.cpp (Hennadii Stepanov)
561e375c73a37934fe77a519762d81edf7a3325c Make PID file creating errors fatal (Hennadii Stepanov)
745a2ace18ce857bc712d7e66c8bad7c082c07e2 Improve PID file removing errors logging (Hennadii Stepanov)
Pull request description:
Digging into #15240 the lack of the proper logging has been discovered.
Fixed by this PR.
UPDATE (inspired by @laanwj's [comment](https://github.com/bitcoin/bitcoin/pull/15278#discussion_r252641810)):
Not being able to create the PID file is fatal now.
Output of `bitcoind`:
```
$ src/bitcoind -pid=/run/bitcoind/bitcoind.pid
2019-02-01T23:20:10Z Bitcoin Core version v0.17.99.0-561e375c7 (release build)
2019-02-01T23:20:10Z Assuming ancestors of block 0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75 have valid signatures.
2019-02-01T23:20:10Z Setting nMinimumChainWork=00000000000000000000000000000000000000000000007dbe94253893cbd463
2019-02-01T23:20:10Z Using the 'sse4(1way),sse41(4way),avx2(8way)' SHA256 implementation
2019-02-01T23:20:10Z Using RdRand as an additional entropy source
2019-02-01T23:20:11Z Error: Unable to create the PID file '/run/bitcoind/bitcoind.pid': No such file or directory
Error: Unable to create the PID file '/run/bitcoind/bitcoind.pid': No such file or directory
2019-02-01T23:20:11Z Shutdown: In progress...
2019-02-01T23:20:11Z Shutdown: Unable to remove PID file: File does not exist
2019-02-01T23:20:11Z Shutdown: done
```
Output of `bitcoin-qt`:
![screenshot from 2019-02-02 01-19-05](https://user-images.githubusercontent.com/32963518/52154886-9349b600-2688-11e9-8128-470f16790305.png)
**Notes for reviewers**
1. `CreatePidFile()` has been moved from `util/system.cpp` to `init.cpp` for the following reasons:
- to get the ability to use `InitError()`
- now `init.cpp` contains code of both creating PID file and removing it
2. Regarding 0.18 release process: this PR modifies 1 string and introduces 2 new ones.
Tree-SHA512: ac07d0f800e61ec759e427d0afc0ca43d67f232e977662253963afdd0a220d34b871050f58149fc9fabd427bfc8e0d3f6a6032f2a38f30ad366fc0d074b0f2b3
-rw-r--r-- | src/init.cpp | 37 | ||||
-rw-r--r-- | src/util/system.cpp | 18 | ||||
-rw-r--r-- | src/util/system.h | 5 | ||||
-rwxr-xr-x | test/lint/lint-locale-dependence.sh | 2 |
4 files changed, 35 insertions, 27 deletions
diff --git a/src/init.cpp b/src/init.cpp index 0013319ad5..caab4a5674 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -53,6 +53,8 @@ #include <stdio.h> #ifndef WIN32 +#include <attributes.h> +#include <cerrno> #include <signal.h> #include <sys/stat.h> #endif @@ -92,6 +94,30 @@ std::unique_ptr<BanMan> g_banman; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; +/** + * The PID file facilities. + */ +#ifndef WIN32 +static const char* BITCOIN_PID_FILENAME = "bitcoind.pid"; + +static fs::path GetPidFile() +{ + return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); +} + +NODISCARD static bool CreatePidFile() +{ + FILE* file = fsbridge::fopen(GetPidFile(), "w"); + if (file) { + fprintf(file, "%d\n", getpid()); + fclose(file); + return true; + } else { + return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno))); + } +} +#endif + ////////////////////////////////////////////////////////////////////////////// // // Shutdown @@ -262,9 +288,11 @@ void Shutdown(InitInterfaces& interfaces) #ifndef WIN32 try { - fs::remove(GetPidFile()); + if (!fs::remove(GetPidFile())) { + LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__); + } } catch (const fs::filesystem_error& e) { - LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what()); + LogPrintf("%s: Unable to remove PID file: %s\n", __func__, e.what()); } #endif interfaces.chain_clients.clear(); @@ -1201,7 +1229,10 @@ bool AppInitMain(InitInterfaces& interfaces) const CChainParams& chainparams = Params(); // ********************************************************* Step 4a: application initialization #ifndef WIN32 - CreatePidFile(GetPidFile(), getpid()); + if (!CreatePidFile()) { + // Detailed error printed inside CreatePidFile(). + return false; + } #endif if (LogInstance().m_print_to_file) { if (gArgs.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) { diff --git a/src/util/system.cpp b/src/util/system.cpp index 27ed24d012..6e82de743a 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -74,7 +74,6 @@ const int64_t nStartupTime = GetTime(); const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; -const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; ArgsManager gArgs; @@ -965,23 +964,6 @@ std::string ArgsManager::GetChainName() const return CBaseChainParams::MAIN; } -#ifndef WIN32 -fs::path GetPidFile() -{ - return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); -} - -void CreatePidFile(const fs::path &path, pid_t pid) -{ - FILE* file = fsbridge::fopen(path, "w"); - if (file) - { - fprintf(file, "%d\n", pid); - fclose(file); - } -} -#endif - bool RenameOver(fs::path src, fs::path dest) { #ifdef WIN32 diff --git a/src/util/system.h b/src/util/system.h index 8867e49478..69ae11d1ed 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -40,7 +40,6 @@ int64_t GetStartupTime(); extern const char * const BITCOIN_CONF_FILENAME; -extern const char * const BITCOIN_PID_FILENAME; /** Translate a message to the native language of the user. */ const extern std::function<std::string(const char*)> G_TRANSLATION_FUN; @@ -86,10 +85,6 @@ const fs::path &GetBlocksDir(); const fs::path &GetDataDir(bool fNetSpecific = true); void ClearDatadirCache(); fs::path GetConfigFile(const std::string& confPath); -#ifndef WIN32 -fs::path GetPidFile(); -void CreatePidFile(const fs::path &path, pid_t pid); -#endif #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh index 1534d5ef68..2b6c78c2c8 100755 --- a/test/lint/lint-locale-dependence.sh +++ b/test/lint/lint-locale-dependence.sh @@ -8,6 +8,7 @@ KNOWN_VIOLATIONS=( "src/dbwrapper.cpp:.*vsnprintf" "src/httprpc.cpp.*trim" "src/init.cpp:.*atoi" + "src/init.cpp:.*fprintf" "src/qt/rpcconsole.cpp:.*atoi" "src/rest.cpp:.*strtol" "src/test/dbwrapper_tests.cpp:.*snprintf" @@ -18,7 +19,6 @@ KNOWN_VIOLATIONS=( "src/util/strencodings.cpp:.*strtoul" "src/util/strencodings.h:.*atoi" "src/util/system.cpp:.*atoi" - "src/util/system.cpp:.*fprintf" ) REGEXP_IGNORE_EXTERNAL_DEPENDENCIES="^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h|univalue/)" |