lightningd: correctly exit when an important-plugin fails to start.

This was found by tests/test_plugin.py::test_important_plugin and
was NOT a flake!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: only just committed
This commit is contained in:
Rusty Russell 2022-11-30 13:07:46 +10:30 committed by Christian Decker
parent 110ed3b1a9
commit 19300de58f
5 changed files with 18 additions and 7 deletions

View file

@ -968,6 +968,7 @@ struct chain_topology *new_topology(struct lightningd *ld, struct log *log)
topo->feerate_uninitialized = true;
topo->root = NULL;
topo->sync_waiters = tal(topo, struct list_head);
topo->extend_timer = NULL;
topo->stopping = false;
list_head_init(topo->sync_waiters);

View file

@ -876,7 +876,7 @@ int main(int argc, char *argv[])
struct htlc_in_map *unconnected_htlcs_in;
struct ext_key *bip32_base;
int sigchld_rfd;
struct io_conn *sigchld_conn;
struct io_conn *sigchld_conn = NULL;
int exit_code = 0;
char **orig_argv;
bool try_reexec;
@ -1104,7 +1104,8 @@ int main(int argc, char *argv[])
/*~ Now that the rpc path exists, we can start the plugins and they
* can start talking to us. */
plugins_config(ld->plugins);
if (!plugins_config(ld->plugins))
goto stop;
/*~ Process any HTLCs we were in the middle of when we exited, now
* that plugins (who might want to know via htlc_accepted hook) are
@ -1201,6 +1202,7 @@ int main(int argc, char *argv[])
assert(io_loop_ret == ld);
log_debug(ld->log, "io_loop_with_timers: %s", __func__);
stop:
/* Stop *new* JSON RPC requests. */
jsonrpc_stop_listening(ld->jsonrpc);

View file

@ -1938,7 +1938,7 @@ plugin_config(struct plugin *plugin)
plugin->plugin_state = AWAITING_INIT_RESPONSE;
}
void plugins_config(struct plugins *plugins)
bool plugins_config(struct plugins *plugins)
{
struct plugin *p;
list_for_each(&plugins->plugins, p, list) {
@ -1948,10 +1948,15 @@ void plugins_config(struct plugins *plugins)
/* Wait for them to configure, before continuing: large
* nodes can take a while to startup! */
if (plugins->startup)
io_loop_with_timers(plugins->ld);
if (plugins->startup) {
/* This happens if an important plugin fails init,
* or if they call shutdown now. */
if (io_loop_with_timers(plugins->ld) == plugins->ld)
return false;
}
plugins->startup = false;
return true;
}
/** json_add_opt_plugins_array

View file

@ -265,8 +265,11 @@ struct command_result *plugin_register_all_complete(struct lightningd *ld,
* and send them over to the plugin. This finalizes the initialization
* of the plugins and signals that lightningd is now ready to process
* incoming JSON-RPC calls and messages.
*
* It waits for plugins to be initialized, but returns false if we
* should exit (an important plugin failed, or we got a shutdown command).
*/
void plugins_config(struct plugins *plugins);
bool plugins_config(struct plugins *plugins);
/**
* This populates the jsonrpc request with the plugin/lightningd specifications

View file

@ -168,7 +168,7 @@ struct chain_topology *new_topology(struct lightningd *ld UNNEEDED, struct log *
void onchaind_replay_channels(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "onchaind_replay_channels called!\n"); abort(); }
/* Generated stub for plugins_config */
void plugins_config(struct plugins *plugins UNNEEDED)
bool plugins_config(struct plugins *plugins UNNEEDED)
{ fprintf(stderr, "plugins_config called!\n"); abort(); }
/* Generated stub for plugins_init */
void plugins_init(struct plugins *plugins UNNEEDED)