Skip to content

Commit 0bd73e2

Browse files
committed
util: Add -shutdownnotify option.
1 parent 75cbbfa commit 0bd73e2

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/init.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,24 @@ static fs::path GetPidFile(const ArgsManager& args)
189189
// shutdown thing.
190190
//
191191

192+
#if HAVE_SYSTEM
193+
static void ShutdownNotify(const ArgsManager& args)
194+
{
195+
std::vector<std::thread> threads;
196+
for (const auto& cmd : args.GetArgs("-shutdownnotify")) {
197+
threads.emplace_back(runCommand, cmd);
198+
}
199+
for (auto& t : threads) {
200+
t.join();
201+
}
202+
}
203+
#endif
204+
192205
void Interrupt(NodeContext& node)
193206
{
207+
#if HAVE_SYSTEM
208+
ShutdownNotify(*node.args);
209+
#endif
194210
InterruptHTTPServer();
195211
InterruptHTTPRPC();
196212
InterruptRPC();
@@ -439,6 +455,7 @@ void SetupServerArgs(ArgsManager& argsman)
439455
argsman.AddArg("-settings=<file>", strprintf("Specify path to dynamic settings data file. Can be disabled with -nosettings. File is written at runtime and not meant to be edited by users (use %s instead for custom settings). Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME, BITCOIN_SETTINGS_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
440456
#if HAVE_SYSTEM
441457
argsman.AddArg("-startupnotify=<cmd>", "Execute command on startup.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
458+
argsman.AddArg("-shutdownnotify=<cmd>", "Execute command immediately before beginning shutdown. The need for shutdown may be urgent, so be careful not to delay it long (if the command doesn't require interaction with the server, consider having it fork into the background).", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
442459
#endif
443460
#ifndef WIN32
444461
argsman.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

test/functional/feature_notifications.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,26 @@ def set_test_params(self):
2828
self.num_nodes = 2
2929
self.setup_clean_chain = True
3030
# The experimental syscall sandbox feature (-sandbox) is not compatible with -alertnotify,
31-
# -blocknotify or -walletnotify (which all invoke execve).
31+
# -blocknotify, -walletnotify or -shutdownnotify (which all invoke execve).
3232
self.disable_syscall_sandbox = True
3333

3434
def setup_network(self):
3535
self.wallet = ''.join(chr(i) for i in range(FILE_CHAR_START, FILE_CHAR_END) if chr(i) not in FILE_CHARS_DISALLOWED)
3636
self.alertnotify_dir = os.path.join(self.options.tmpdir, "alertnotify")
3737
self.blocknotify_dir = os.path.join(self.options.tmpdir, "blocknotify")
3838
self.walletnotify_dir = os.path.join(self.options.tmpdir, "walletnotify")
39+
self.shutdownnotify_dir = os.path.join(self.options.tmpdir, "shutdownnotify")
40+
self.shutdownnotify_file = os.path.join(self.shutdownnotify_dir, "shutdownnotify.txt")
3941
os.mkdir(self.alertnotify_dir)
4042
os.mkdir(self.blocknotify_dir)
4143
os.mkdir(self.walletnotify_dir)
44+
os.mkdir(self.shutdownnotify_dir)
4245

4346
# -alertnotify and -blocknotify on node0, walletnotify on node1
4447
self.extra_args = [[
4548
f"-alertnotify=echo > {os.path.join(self.alertnotify_dir, '%s')}",
4649
f"-blocknotify=echo > {os.path.join(self.blocknotify_dir, '%s')}",
50+
f"-shutdownnotify=echo > {self.shutdownnotify_file}",
4751
], [
4852
f"-walletnotify=echo %h_%b > {os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))}",
4953
]]
@@ -159,6 +163,10 @@ def run_test(self):
159163

160164
# TODO: add test for `-alertnotify` large fork notifications
161165

166+
self.log.info("test -shutdownnotify")
167+
self.stop_nodes()
168+
self.wait_until(lambda: os.path.isfile(self.shutdownnotify_file), timeout=10)
169+
162170
def expect_wallet_notify(self, tx_details):
163171
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_details), timeout=10)
164172
# Should have no more and no less files than expected

0 commit comments

Comments
 (0)