From 0d441bdb8b07839caf449b5a8bacfddf6def35e7 Mon Sep 17 00:00:00 2001 From: Michael Schmoock Date: Thu, 17 Jun 2021 17:17:41 +0200 Subject: [PATCH] plugin: rescan restarts plugin on update This adds a `u32 checksum` field to the plugin struct that is used to identify if a plugin is outdated and needs to be restarted on `rescan`. Note: Only affects non-important plugins. Changelog-Added: Plugin: Restart plugin on `rescan` when binary was changed. --- lightningd/plugin.c | 24 +++++++++++++++++++++--- lightningd/plugin.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 5c32c72e0757..720853997544 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -215,21 +217,36 @@ static void destroy_plugin(struct plugin *p) } } +static u32 file_checksum(const char* path) +{ + char *content = grab_file(path, path); + if (content == NULL) return 0; + return crc32c(0, content, tal_count(content)); +} + struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES, struct command *start_cmd, bool important, const char *parambuf STEALS, const jsmntok_t *params STEALS) { struct plugin *p, *p_temp; + u32 chksum; /* Don't register an already registered plugin */ list_for_each(&plugins->plugins, p_temp, list) { if (streq(path, p_temp->cmd)) { - if (taken(path)) - tal_free(path); - /* If added as "important", upgrade to "important". */ + /* If added as "important", upgrade to "important". */ if (important) p_temp->important = true; + /* stop and restart plugin on different checksum */ + chksum = file_checksum(path); + if (p_temp->checksum != chksum && !p_temp->important) { + plugin_kill(p_temp, LOG_INFORM, + "Plugin changed, needs restart."); + break; + } + if (taken(path)) + tal_free(path); return NULL; } } @@ -237,6 +254,7 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES, p = tal(plugins, struct plugin); p->plugins = plugins; p->cmd = tal_strdup(p, path); + p->checksum = file_checksum(p->cmd); p->shortname = path_basename(p, p->cmd); p->start_cmd = start_cmd; diff --git a/lightningd/plugin.h b/lightningd/plugin.h index 9fae129cf649..92854e6143fa 100644 --- a/lightningd/plugin.h +++ b/lightningd/plugin.h @@ -48,6 +48,7 @@ struct plugin { pid_t pid; char *cmd; + u32 checksum; struct io_conn *stdin_conn, *stdout_conn; struct plugins *plugins; const char **plugin_path;