Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
shell: abstract some shell internals into "builtin plugins" #2335
I hesitated to post this PR, because I belatedly realized the plugin interface developed here was a bit of a misstep, but perhaps it is enough of a step forward for a review of the general direction, or a mercy merge for other reasons (see below)
This PR includes:
However, this PR does abstract
garlick left a comment
I found a few unchecked mallocs probably left over from when you were prototyping this, and possible errno clobbering (sorry if that's not intended to be used - I was reviewing the diff which doesn't always give the full picture).
In general, I really like how this abstracts the builtins further from the core shell code!
My vote is to get this in and decide what additional work needs to be done to complete it. It looks to me like a good step forward. I apologize for not being too helpful in the design due to lack of experience in this sort of thing. You have my ringing endorsement FWIW!
Yeah, your comments are spot on. The existing "plugstack" thing is really just a prototype (I haven't decided how to deal with errors at all yet), but I realized after the fact that the approach won't work in its current form, so it needs to be rewritten or replaced. (Thanks for taking a look though)
I wasn't sure if people would want an intermediate step like this merged while I try something else, or if we'd rather wait a few days to get the final working thing in. If we want to get this merged I'll go back and address your comments asap to get the current code acceptable at least (I do feel like the abstraction of the "builtin" plugins was a win, so that, at least, is a small step forward)
The main features we'll keep from the "plugstack" prototype I think are the ability to create compiled-in plugins by assigning arbitrary functions to plugin "symbols", and the ability to register plugins with names that override previously loaded plugins.
I vote for merging the intermediate step.
Ok, I've pushed a change to remove the dso loading support from plugstack.c since it isn't used here, and therefore change the title of this PR accordingly.
I've also attempted to address the remaining review comments by augmenting the plugstack prototype with return value checking, use of saved_errno in free functions, etc.
If the current state of the code is acceptable as a very minor step forward. We could merge this and I can work on redoing the dynamic loading of plugins next.
Prepare to make a shell plugin interface public as <flux/shell.h>. Move struct flux_shell definition into an "internal.h" header and keep existing public flux_shell_* functions in shell.h. Add shell.h to src/include/flux so that existing components may include it as <flux/shell.h>. Update current users. No interfaces have been added or removed.
To allow builtin shell modules to "#include <flux/shell.h>" like out-of-tree plugins would. Add src/include/shell.h as a wrapper for src/shell/shell.h.
Add a simple plugin stack interface for use by the flux-shell. The plugstack interface supports loading DSOs with arbitrary callback symbols and an optional plugin name. Callbacks are called in the order in which plugins are loaded, except in the case of a name collision, in which case the last plugin loaded will override the original. This interface alone doesn't support a config file or other method for configuring how and when plugins are loaded. That is left for a higher level.
Add a pointer to the currently starting task in the shell. This will be required for plugin interfaces that want to fetch the currently "active" task.
Add a method for shell plugins to fetch the current shell task, if valid, as well as accessors for the task's flux_cmd_t and flux_subprocess_t members. Additionally, prepare for task plugins to be able to "subscribe" to channel output via flux_shell_task_channel_subscribe(), though the method doesn't do anything yet besides track subscribers.
Add plugin callback sites to the shell in the following places: - flux_shell_init - called during shell intialization - flux_shell_exit - called just before shell exit - flux_shell_task_init - called for each task before fork/exec - flux_shell_task_fork - called from parent after task is forked - flux_shell_task_exec - called from child before exec(2) No plugins are registered at this time so all these calls do nothing.
Add support for loading shell internal plugins. Shell 'builtins' are loaded onto the plugstack, but the provided plugin functions are statically linked into the program. Besides a cleaner abstraction, the main benefit of shell plugins is that they are loaded into the plugin stack under a well-known name, and thus may be overridden later by alternate, dynamically loaded plugins. Currently, no builtin plugins are loaded.
Untangle the PMI implementation from the rest of the shell and turn it into a shell builtin plugin under the name "pmi". This allows, in theory, the default PMI implementation to be overridden by a dynamically loaded plugin. There is a bit of cheating here since the pmi plugin actually has access to shell internals, however in order to simplify development we allow this violation of the shell plugin abstraction for builtins.
Untangle the io implementation from the shell internals and abstract the module into a builtin shell plugin.
Problem: The output plugin is contained in a file called "io.c" and includes a struct and set of functions that use "io" in the name, when this module really only deals with output. This could cause confusion when an eventual "input" plugin is added to the shell. Rename everything that uses "io" in the name to use "output" instead.
@@ Coverage Diff @@ ## master #2335 +/- ## ========================================== - Coverage 80.87% 80.82% -0.06% ========================================== Files 215 217 +2 Lines 34333 34494 +161 ========================================== + Hits 27768 27880 +112 - Misses 6565 6614 +49