Skip to content

Commit 8f6ab31

Browse files
committed
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 belonging to the first instance would be erroneously removed by the second process shutting down. Fix this to only delete the PID file if we created it.
1 parent 160d236 commit 8f6ab31

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

src/init.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map";
155155
* The PID file facilities.
156156
*/
157157
static const char* BITCOIN_PID_FILENAME = "bitcoind.pid";
158+
/**
159+
* True if this process has created a PID file.
160+
* Used to determine whether we should remove the PID file on shutdown.
161+
*/
162+
static bool g_generated_pid{false};
158163

159164
static fs::path GetPidFile(const ArgsManager& args)
160165
{
@@ -170,12 +175,24 @@ static fs::path GetPidFile(const ArgsManager& args)
170175
#else
171176
tfm::format(file, "%d\n", getpid());
172177
#endif
178+
g_generated_pid = true;
173179
return true;
174180
} else {
175181
return InitError(strprintf(_("Unable to create the PID file '%s': %s"), fs::PathToString(GetPidFile(args)), SysErrorString(errno)));
176182
}
177183
}
178184

185+
static void RemovePidFile(const ArgsManager& args)
186+
{
187+
if (!g_generated_pid) return;
188+
const auto pid_path{GetPidFile(args)};
189+
if (std::error_code error; !fs::remove(pid_path, error)) {
190+
std::string msg{error ? error.message() : "File does not exist"};
191+
LogPrintf("Unable to remove PID file (%s): %s\n", fs::PathToString(pid_path), msg);
192+
}
193+
}
194+
195+
179196
//////////////////////////////////////////////////////////////////////////////
180197
//
181198
// Shutdown
@@ -352,13 +369,7 @@ void Shutdown(NodeContext& node)
352369
node.scheduler.reset();
353370
node.kernel.reset();
354371

355-
try {
356-
if (!fs::remove(GetPidFile(*node.args))) {
357-
LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__);
358-
}
359-
} catch (const fs::filesystem_error& e) {
360-
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
361-
}
372+
RemovePidFile(*node.args);
362373

363374
LogPrintf("%s: done\n", __func__);
364375
}

test/functional/feature_filelock.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ def run_test(self):
3030
expected_msg = f"Error: Cannot obtain a lock on data directory {datadir}. {self.config['environment']['PACKAGE_NAME']} is probably already running."
3131
self.nodes[1].assert_start_raises_init_error(extra_args=[f'-datadir={self.nodes[0].datadir_path}', '-noserver'], expected_msg=expected_msg)
3232

33+
self.log.info("Check that cookie and PID file are not deleted when attempting to start a second bitcoind using the same datadir")
3334
cookie_file = datadir / ".cookie"
3435
assert cookie_file.exists() # should not be deleted during the second bitcoind instance shutdown
36+
pid_file = datadir / "bitcoind.pid"
37+
assert pid_file.exists()
3538

3639
if self.is_wallet_compiled():
3740
def check_wallet_filelock(descriptors):

0 commit comments

Comments
 (0)