From 98ba5ba0cc0cb94b51595248041db972a9ef5a09 Mon Sep 17 00:00:00 2001 From: willcl-ark Date: Mon, 27 Nov 2023 10:29:02 +0000 Subject: [PATCH] init: don't delete PID file if it was not generated Previously, starting a second bitcoind using the same datadir would correctly fail to init and shutdown. However during shutdown the PID file from the first instance would be erroneously removed. Fix this to only delete the PID file is we created it. --- src/init.cpp | 23 ++++++++++++++++------- test/functional/feature_filelock.py | 4 ++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index d6dc62f707ff45..afa0ab1ee6ba6b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -155,6 +155,7 @@ static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map"; * The PID file facilities. */ static const char* BITCOIN_PID_FILENAME = "bitcoind.pid"; +static bool g_generated_pid{false}; static fs::path GetPidFile(const ArgsManager& args) { @@ -170,12 +171,26 @@ static fs::path GetPidFile(const ArgsManager& args) #else tfm::format(file, "%d\n", getpid()); #endif + g_generated_pid = true; return true; } else { return InitError(strprintf(_("Unable to create the PID file '%s': %s"), fs::PathToString(GetPidFile(args)), SysErrorString(errno))); } } +static void RemovePidFile(const ArgsManager& args) +{ + if (!g_generated_pid) return; + try { + if (!fs::remove(GetPidFile(args))) { + LogPrintf("Unable to remove PID file: File does not exist\n"); + } + } catch (const fs::filesystem_error& e) { + LogPrintf("Unable to remove PID file: %s\n", fsbridge::get_filesystem_error_message(e)); + } +} + + ////////////////////////////////////////////////////////////////////////////// // // Shutdown @@ -349,13 +364,7 @@ void Shutdown(NodeContext& node) node.scheduler.reset(); node.kernel.reset(); - try { - if (!fs::remove(GetPidFile(*node.args))) { - LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__); - } - } catch (const fs::filesystem_error& e) { - LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); - } + RemovePidFile(*node.args); LogPrintf("%s: done\n", __func__); } diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py index 24a68a04bfcac4..1a31dd06f35ce2 100755 --- a/test/functional/feature_filelock.py +++ b/test/functional/feature_filelock.py @@ -30,6 +30,10 @@ def run_test(self): expected_msg = f"Error: Cannot obtain a lock on data directory {datadir}. {self.config['environment']['PACKAGE_NAME']} is probably already running." self.nodes[1].assert_start_raises_init_error(extra_args=[f'-datadir={self.nodes[0].datadir_path}', '-noserver'], expected_msg=expected_msg) + self.log.info("Check that cookie and PID files are not deleted when attempting to start a second bitcoind using the same datadir") + pid_file = datadir / "bitcoind.pid" + assert pid_file.exists() + if self.is_wallet_compiled(): def check_wallet_filelock(descriptors): wallet_name = ''.join([random.choice(string.ascii_lowercase) for _ in range(6)])