@@ -27,32 +27,13 @@ static struct command_result *plugin_dynamic_list_plugins(struct command *cmd,
2727 json_add_string (response , "name" , p -> cmd );
2828 json_add_bool (response , "active" ,
2929 p -> plugin_state == INIT_COMPLETE );
30+ json_add_u32 (response , "state" , p -> plugin_state );
3031 json_object_end (response );
3132 }
3233 json_array_end (response );
3334 return command_success (cmd , response );
3435}
3536
36- /* Mutual recursion. */
37- static void plugin_dynamic_crash (struct plugin * plugin , struct dynamic_plugin * dp );
38-
39- /**
40- * Returned by all subcommands on error.
41- */
42- static struct command_result *
43- plugin_dynamic_error (struct dynamic_plugin * dp , const char * error )
44- {
45- if (dp -> plugin )
46- plugin_kill (dp -> plugin , "%s" , error );
47- else
48- log_info (dp -> cmd -> ld -> log , "%s" , error );
49-
50- tal_del_destructor2 (dp -> plugin , plugin_dynamic_crash , dp );
51- return command_fail (dp -> cmd , JSONRPC2_INVALID_PARAMS ,
52- "%s: %s" , dp -> plugin ? dp -> plugin -> cmd : "unknown plugin" ,
53- error );
54- }
55-
5637struct command_result * plugin_cmd_killed (struct command * cmd ,
5738 struct plugin * plugin , const char * msg )
5839{
@@ -71,143 +52,27 @@ struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
7152 return plugin_dynamic_list_plugins (cmd , plugins );
7253}
7354
74- static void plugin_dynamic_timeout (struct dynamic_plugin * dp )
75- {
76- plugin_dynamic_error (dp , "Timed out while waiting for plugin response" );
77- }
78-
79- static void plugin_dynamic_crash (struct plugin * p , struct dynamic_plugin * dp )
80- {
81- plugin_dynamic_error (dp , "Plugin exited before completing handshake." );
82- }
83-
84- static void plugin_dynamic_config_callback (const char * buffer ,
85- const jsmntok_t * toks ,
86- const jsmntok_t * idtok ,
87- struct dynamic_plugin * dp )
88- {
89- struct plugin * p ;
90-
91- dp -> plugin -> plugin_state = INIT_COMPLETE ;
92- /* Reset the timer only now so that we are either configured, or
93- * killed. */
94- tal_free (dp -> plugin -> timeout_timer );
95- tal_del_destructor2 (dp -> plugin , plugin_dynamic_crash , dp );
96-
97- list_for_each (& dp -> plugin -> plugins -> plugins , p , list ) {
98- if (p -> plugin_state != INIT_COMPLETE )
99- return ;
100- }
101-
102- /* No plugin unconfigured left, return the plugin list */
103- was_pending (plugin_dynamic_list_plugins (dp -> cmd , dp -> plugin -> plugins ));
104- }
105-
106- /**
107- * Send the init message to the plugin. We don't care about its response,
108- * but it's considered the last part of the handshake : once it responds
109- * it is considered configured.
110- */
111- static void plugin_dynamic_config (struct dynamic_plugin * dp )
112- {
113- struct jsonrpc_request * req ;
114-
115- req = jsonrpc_request_start (dp -> plugin , "init" , dp -> plugin -> log ,
116- plugin_dynamic_config_callback , dp );
117- plugin_populate_init_request (dp -> plugin , req );
118- jsonrpc_request_end (req );
119- dp -> plugin -> plugin_state = AWAITING_INIT_RESPONSE ;
120- plugin_request_send (dp -> plugin , req );
121- }
122-
123- static void plugin_dynamic_manifest_callback (const char * buffer ,
124- const jsmntok_t * toks ,
125- const jsmntok_t * idtok ,
126- struct dynamic_plugin * dp )
127- {
128- if (!plugin_parse_getmanifest_response (buffer , toks , idtok , dp -> plugin ))
129- return was_pending (plugin_dynamic_error (dp , "Gave a bad response to getmanifest" ));
130-
131- if (!dp -> plugin -> dynamic )
132- return was_pending (plugin_dynamic_error (dp , "Not a dynamic plugin" ));
133-
134- /* We got the manifest, now send the init message */
135- dp -> plugin -> plugin_state = NEEDS_INIT ;
136- plugin_dynamic_config (dp );
137- }
138-
139- /**
140- * This starts a plugin : spawns the process, connect its stdout and stdin,
141- * then sends it a getmanifest request.
142- */
143- static struct command_result * plugin_start (struct dynamic_plugin * dp )
144- {
145- int stdin , stdout ;
146- mode_t prev_mask ;
147- char * * p_cmd ;
148- struct jsonrpc_request * req ;
149- struct plugin * p = dp -> plugin ;
150-
151- p -> dynamic = false;
152- p_cmd = tal_arrz (NULL , char * , 2 );
153- p_cmd [0 ] = p -> cmd ;
154- /* In case the plugin create files, this is a better default. */
155- prev_mask = umask (dp -> cmd -> ld -> initial_umask );
156- p -> pid = pipecmdarr (& stdin , & stdout , & pipecmd_preserve , p_cmd );
157- umask (prev_mask );
158- if (p -> pid == -1 )
159- return plugin_dynamic_error (dp , "Error running command" );
160- else
161- log_debug (dp -> cmd -> ld -> plugins -> log , "started(%u) %s" , p -> pid , p -> cmd );
162- tal_free (p_cmd );
163- p -> buffer = tal_arr (p , char , 64 );
164- p -> stop = false;
165- /* Give the plugin 20 seconds to respond to `getmanifest`, so we don't hang
166- * too long on the RPC caller. */
167- p -> timeout_timer = new_reltimer (dp -> cmd -> ld -> timers , dp ,
168- time_from_sec ((20 )),
169- plugin_dynamic_timeout , dp );
170-
171- /* Besides the timeout we could also have the plugin crash before
172- * completing the handshake. In that case we'll get notified and we
173- * can clean up the `struct dynamic_plugin` and return an appropriate
174- * error.
175- *
176- * The destructor is deregistered in the following places:
177- *
178- * - plugin_dynamic_error in case of a timeout or a crash
179- * - plugin_dynamic_config_callback if the handshake completes
180- */
181- tal_add_destructor2 (p , plugin_dynamic_crash , dp );
182-
183- /* Create two connections, one read-only on top of the plugin's stdin, and one
184- * write-only on its stdout. */
185- io_new_conn (p , stdout , plugin_stdout_conn_init , p );
186- io_new_conn (p , stdin , plugin_stdin_conn_init , p );
187- req = jsonrpc_request_start (p , "getmanifest" , p -> log ,
188- plugin_dynamic_manifest_callback , dp );
189- jsonrpc_request_end (req );
190- plugin_request_send (p , req );
191- p -> plugin_state = AWAITING_GETMANIFEST_RESPONSE ;
192- return command_still_pending (dp -> cmd );
193- }
194-
19555/**
19656 * Called when trying to start a plugin through RPC, it starts the plugin and
19757 * will give a result 20 seconds later at the most.
19858 */
19959static struct command_result *
20060plugin_dynamic_start (struct command * cmd , const char * plugin_path )
20161{
202- struct dynamic_plugin * dp ;
62+ struct plugin * p = plugin_register ( cmd -> ld -> plugins , plugin_path , cmd ) ;
20363
204- dp = tal (cmd , struct dynamic_plugin );
205- dp -> cmd = cmd ;
206- dp -> plugin = plugin_register (cmd -> ld -> plugins , plugin_path , NULL );
207- if (!dp -> plugin )
208- return plugin_dynamic_error (dp , "Is already registered" );
64+ if (!p )
65+ return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
66+ "%s: already registered" ,
67+ plugin_path );
20968
210- return plugin_start (dp );
69+ /* This will come back via plugin_cmd_killed or plugin_cmd_succeeded */
70+ if (!plugin_send_getmanifest (p ))
71+ return command_fail (cmd , PLUGIN_ERROR ,
72+ "%s: failed to open: %s" ,
73+ plugin_path , strerror (errno ));
74+
75+ return command_still_pending (cmd );
21176}
21277
21378/**
@@ -218,38 +83,23 @@ static struct command_result *
21883plugin_dynamic_startdir (struct command * cmd , const char * dir_path )
21984{
22085 const char * err ;
221- struct plugin * p ;
222- /* If the directory is empty */
223- bool found ;
86+ struct command_result * res ;
22487
22588 err = add_plugin_dir (cmd -> ld -> plugins , dir_path , false);
22689 if (err )
22790 return command_fail (cmd , JSONRPC2_INVALID_PARAMS , "%s" , err );
22891
229- found = false;
230- list_for_each (& cmd -> ld -> plugins -> plugins , p , list ) {
231- if (p -> plugin_state == UNCONFIGURED ) {
232- found = true;
233- struct dynamic_plugin * dp = tal (cmd , struct dynamic_plugin );
234- dp -> plugin = p ;
235- dp -> cmd = cmd ;
236- plugin_start (dp );
237- }
238- }
239- if (!found )
240- plugin_dynamic_list_plugins (cmd , cmd -> ld -> plugins );
92+ /* If none added, this calls plugin_cmd_all_complete immediately */
93+ res = plugin_register_all_complete (cmd -> ld , cmd );
94+ if (res )
95+ return res ;
24196
97+ plugins_send_getmanifest (cmd -> ld -> plugins );
24298 return command_still_pending (cmd );
24399}
244100
245101static void clear_plugin (struct plugin * p , const char * name )
246102{
247- struct plugin_opt * opt ;
248-
249- list_for_each (& p -> plugin_opts , opt , list )
250- if (!opt_unregister (opt -> name ))
251- fatal ("Could not unregister %s from plugin %s" ,
252- opt -> name , name );
253103 plugin_kill (p , "%s stopped by lightningd via RPC" , name );
254104 tal_free (p );
255105}
@@ -290,25 +140,16 @@ plugin_dynamic_stop(struct command *cmd, const char *plugin_name)
290140static struct command_result *
291141plugin_dynamic_rescan_plugins (struct command * cmd )
292142{
293- bool found ;
294- struct plugin * p ;
143+ struct command_result * res ;
295144
296145 /* This will not fail on "already registered" error. */
297146 plugins_add_default_dir (cmd -> ld -> plugins );
298147
299- found = false;
300- list_for_each (& cmd -> ld -> plugins -> plugins , p , list ) {
301- if (p -> plugin_state == UNCONFIGURED ) {
302- struct dynamic_plugin * dp = tal (cmd , struct dynamic_plugin );
303- dp -> plugin = p ;
304- dp -> cmd = cmd ;
305- plugin_start (dp );
306- found = true;
307- }
308- }
148+ /* If none added, this calls plugin_cmd_all_complete immediately */
149+ res = plugin_register_all_complete (cmd -> ld , cmd );
150+ if (res )
151+ return res ;
309152
310- if (!found )
311- return plugin_dynamic_list_plugins (cmd , cmd -> ld -> plugins );
312153 return command_still_pending (cmd );
313154}
314155
0 commit comments