mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-23 15:04:19 +01:00
lightningd/plugin.c: Add important plugins, which if they terminate, lightningd also terminates.
Changelog-Added: New option `--important-plugin` loads a plugin is so important that if it dies, `lightningd` will exit rather than continue. You can still `--disable-plugin` it, however, which trumps `--important-plugin` and it will not be started at all.
This commit is contained in:
committed by
neil saitug
parent
50600dce95
commit
a847487bbe
@@ -53,6 +53,7 @@ struct plugins *plugins_new(const tal_t *ctx, struct log_book *log_book,
|
||||
p->startup = true;
|
||||
p->json_cmds = tal_arr(p, struct command *, 0);
|
||||
p->blacklist = tal_arr(p, const char *, 0);
|
||||
p->shutdown = false;
|
||||
uintmap_init(&p->pending_requests);
|
||||
memleak_add_helper(p, memleak_help_pending_requests);
|
||||
|
||||
@@ -62,6 +63,9 @@ struct plugins *plugins_new(const tal_t *ctx, struct log_book *log_book,
|
||||
void plugins_free(struct plugins *plugins)
|
||||
{
|
||||
struct plugin *p;
|
||||
|
||||
plugins->shutdown = true;
|
||||
|
||||
/* Plugins are usually the unit of allocation, and they are internally
|
||||
* consistent, so let's free each plugin first. */
|
||||
while (!list_empty(&plugins->plugins)) {
|
||||
@@ -105,6 +109,7 @@ struct command_result *plugin_register_all_complete(struct lightningd *ld,
|
||||
static void destroy_plugin(struct plugin *p)
|
||||
{
|
||||
struct plugin_rpccall *call;
|
||||
|
||||
plugin_hook_unregister_all(p);
|
||||
list_del(&p->list);
|
||||
|
||||
@@ -118,10 +123,23 @@ static void destroy_plugin(struct plugin *p)
|
||||
/* Don't call this if we're still parsing options! */
|
||||
if (p->plugin_state != UNCONFIGURED)
|
||||
check_plugins_resolved(p->plugins);
|
||||
|
||||
/* If we are shutting down, do not continue to checking if
|
||||
* the dying plugin is important. */
|
||||
if (p->plugins->shutdown)
|
||||
return;
|
||||
|
||||
/* Now check if the dying plugin is important. */
|
||||
if (p->important) {
|
||||
log_broken(p->log,
|
||||
"Plugin marked as important, "
|
||||
"shutting down lightningd!");
|
||||
lightningd_exit(p->plugins->ld, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||
struct command *start_cmd)
|
||||
struct command *start_cmd, bool important)
|
||||
{
|
||||
struct plugin *p, *p_temp;
|
||||
|
||||
@@ -130,6 +148,9 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||
if (streq(path, p_temp->cmd)) {
|
||||
if (taken(path))
|
||||
tal_free(path);
|
||||
/* If added as "important", upgrade to "important". */
|
||||
if (important)
|
||||
p_temp->important = true;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -153,6 +174,8 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||
list_add_tail(&plugins->plugins, &p->list);
|
||||
tal_add_destructor(p, destroy_plugin);
|
||||
list_head_init(&p->pending_rpccalls);
|
||||
|
||||
p->important = important;
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -186,6 +209,8 @@ void plugin_blacklist(struct plugins *plugins, const char *name)
|
||||
log_info(plugins->log, "%s: disabled via disable-plugin",
|
||||
p->cmd);
|
||||
list_del_from(&plugins->plugins, &p->list);
|
||||
/* disable-plugin overrides important-plugin. */
|
||||
p->important = false;
|
||||
tal_free(p);
|
||||
}
|
||||
}
|
||||
@@ -1188,7 +1213,7 @@ char *add_plugin_dir(struct plugins *plugins, const char *dir, bool error_ok)
|
||||
log_info(plugins->log, "%s: disabled via disable-plugin",
|
||||
fullpath);
|
||||
} else {
|
||||
p = plugin_register(plugins, fullpath, NULL);
|
||||
p = plugin_register(plugins, fullpath, NULL, false);
|
||||
if (!p && !error_ok)
|
||||
return tal_fmt(NULL, "Failed to register %s: %s",
|
||||
fullpath, strerror(errno));
|
||||
@@ -1396,24 +1421,35 @@ void plugins_config(struct plugins *plugins)
|
||||
plugins->startup = false;
|
||||
}
|
||||
|
||||
void json_add_opt_plugins(struct json_stream *response,
|
||||
const struct plugins *plugins)
|
||||
/** json_add_opt_plugins_array
|
||||
*
|
||||
* @brief add a named array of plugins to the given response,
|
||||
* depending on whether it is important or not important.
|
||||
*
|
||||
* @param response - the `json_stream` to write into.
|
||||
* @param name - the field name of the array.
|
||||
* @param plugins - the plugins object to query.
|
||||
* @param important - match the `important` setting of the
|
||||
* plugins to be added.
|
||||
*/
|
||||
static
|
||||
void json_add_opt_plugins_array(struct json_stream *response,
|
||||
const char *name,
|
||||
const struct plugins *plugins,
|
||||
bool important)
|
||||
{
|
||||
struct plugin *p;
|
||||
struct plugin_opt *opt;
|
||||
const char *plugin_name;
|
||||
struct plugin_opt *opt;
|
||||
const char *opt_name;
|
||||
|
||||
/* DEPRECATED: duplicated JSON "plugin" entries */
|
||||
if (deprecated_apis) {
|
||||
list_for_each(&plugins->plugins, p, list) {
|
||||
json_add_string(response, "plugin", p->cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/* we output 'plugins' and their options as an array of substructures */
|
||||
json_array_start(response, "plugins");
|
||||
json_array_start(response, name);
|
||||
list_for_each(&plugins->plugins, p, list) {
|
||||
/* Skip if not matching. */
|
||||
if (p->important != important)
|
||||
continue;
|
||||
|
||||
json_object_start(response, NULL);
|
||||
json_add_string(response, "path", p->cmd);
|
||||
|
||||
@@ -1444,6 +1480,23 @@ void json_add_opt_plugins(struct json_stream *response,
|
||||
json_array_end(response);
|
||||
}
|
||||
|
||||
void json_add_opt_plugins(struct json_stream *response,
|
||||
const struct plugins *plugins)
|
||||
{
|
||||
struct plugin *p;
|
||||
|
||||
json_add_opt_plugins_array(response, "plugins", plugins, false);
|
||||
json_add_opt_plugins_array(response, "important-plugins", plugins, true);
|
||||
|
||||
/* DEPRECATED: duplicated JSON "plugin" entries */
|
||||
if (deprecated_apis) {
|
||||
list_for_each(&plugins->plugins, p, list) {
|
||||
json_add_string(response, p->important ? "important-plugin" : "plugin", p->cmd);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void json_add_opt_disable_plugins(struct json_stream *response,
|
||||
const struct plugins *plugins)
|
||||
{
|
||||
@@ -1546,7 +1599,6 @@ static void mark_plugin_destroyed(const struct plugin *unused,
|
||||
pd->plugin = NULL;
|
||||
}
|
||||
|
||||
|
||||
struct plugin_destroyed *plugin_detect_destruction(const struct plugin *plugin)
|
||||
{
|
||||
struct plugin_destroyed *pd = tal(NULL, struct plugin_destroyed);
|
||||
|
||||
Reference in New Issue
Block a user