Browse Source

plugin: Remove added JSON-RPC methods if a plugin gets killed

Removes the method from the dispatch table, leaving a NULL entry
currently.

Signed-off-by: Christian Decker <@cdecker>
plugin-6
Christian Decker 6 years ago
committed by Rusty Russell
parent
commit
a71208b2a0
  1. 23
      lightningd/jsonrpc.c
  2. 8
      lightningd/jsonrpc.h
  3. 3
      lightningd/lightningd.c
  4. 8
      lightningd/plugin.c

23
lightningd/jsonrpc.c

@ -347,11 +347,12 @@ static const struct json_command *find_cmd(const struct jsonrpc *rpc,
{
struct json_command **commands = rpc->commands;
/* commands[i]->name can be NULL in test code. */
for (size_t i=0; i<tal_count(commands); i++)
if (commands[i]->name &&
json_tok_streq(buffer, tok, commands[i]->name))
return commands[i];
/* commands[i] can be NULL if the plugin that registered it
* was killed, commands[i]->name can be NULL in test code. */
for (size_t i = 0; i < tal_count(commands); i++)
if (commands[i] && commands[i]->name &&
json_tok_streq(buffer, tok, commands[i]->name))
return commands[i];
return NULL;
}
@ -738,6 +739,18 @@ bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command)
return true;
}
void jsonrpc_command_remove(struct jsonrpc *rpc, const char *method)
{
// FIXME: Currently leaves NULL entries in the table, if we
// restart plugins we should shift them out.
for (size_t i=0; i<tal_count(rpc->commands); i++) {
struct json_command *cmd = rpc->commands[i];
if (cmd && streq(cmd->name, method)) {
rpc->commands[i] = tal_free(cmd);
}
}
}
struct jsonrpc *jsonrpc_new(const tal_t *ctx, struct lightningd *ld)
{
struct jsonrpc *jsonrpc = tal(ctx, struct jsonrpc);

8
lightningd/jsonrpc.h

@ -117,5 +117,13 @@ void jsonrpc_listen(struct jsonrpc *rpc, struct lightningd *ld);
*/
bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command);
/**
* Remove a command/method from the JSON-RPC.
*
* Used to dynamically remove a `struct json_command` from the
* JSON-RPC dispatch table by its name.
*/
void jsonrpc_command_remove(struct jsonrpc *rpc, const char *method);
AUTODATA_TYPE(json_command, struct json_command);
#endif /* LIGHTNING_LIGHTNINGD_JSONRPC_H */

3
lightningd/lightningd.c

@ -781,6 +781,8 @@ int main(int argc, char *argv[])
shutdown_subdaemons(ld);
tal_free(ld->plugins);
/* Clean up the JSON-RPC. This needs to happen in a DB transaction since
* it might actually be touching the DB in some destructors, e.g.,
* unreserving UTXOs (see #1737) */
@ -788,7 +790,6 @@ int main(int argc, char *argv[])
tal_free(ld->jsonrpc);
db_commit_transaction(ld->wallet->db);
tal_free(ld->plugins);
remove(ld->pidfile);
/* FIXME: pay can have children off tmpctx which unlink from

8
lightningd/plugin.c

@ -118,6 +118,8 @@ static void plugin_kill(struct plugin *plugin, char *msg)
plugin->stop = true;
io_wake(plugin);
kill(plugin->pid, SIGKILL);
list_del(&plugin->list);
tal_free(plugin);
}
/**
@ -384,8 +386,10 @@ static bool plugin_opts_add(const struct plugin_request *req)
return true;
}
static void plugin_rpcmethod_destroy(struct json_command *cmd)
static void plugin_rpcmethod_destroy(struct json_command *cmd,
struct jsonrpc *rpc)
{
jsonrpc_command_remove(rpc, cmd->name);
}
static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
@ -448,7 +452,7 @@ static bool plugin_rpcmethod_add(struct plugin *plugin, const char *buffer,
cmd->deprecated = false;
cmd->dispatch = plugin_rpcmethod_dispatch;
tal_add_destructor(cmd, plugin_rpcmethod_destroy);
tal_add_destructor2(cmd, plugin_rpcmethod_destroy, plugin->plugins->rpc);
if (!jsonrpc_command_add(plugin->plugins->rpc, cmd)) {
log_broken(plugin->log,
"Could not register method \"%s\", a method with "

Loading…
Cancel
Save