From d40abcaeb305c858d6139bebc9cf5c65bb48ba67 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 | 33 ++++++++++++++++++++++++++++++--- lightningd/plugin.h | 1 + 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 5c32c72e0757..9d2d75cda7a1 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include @@ -215,21 +217,45 @@ static void destroy_plugin(struct plugin *p) } } +static u32 file_checksum(const char* path) +{ + FILE *fp; + char buf[1024]; + size_t nread; + u32 checksum = 0; + + fp = fopen(path, "r"); + if (fp == NULL) + return 0; + while ((nread = fread(buf, 1, sizeof(buf), fp)) > 0) + checksum = crc32c(checksum, &buf, nread); + fclose(fp); + return checksum; +} + 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 +263,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(path); 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;