Add dependency resolver for plugins.

This has been something I wanted to avoid, but then I stumbled so hard
on it myself I simply had to add it.  With this commit finit actually
comes of age -- it's now possible to do anything a modern init can --
only faster! :-)

Included in this commit is the OpenBSD version of sys/queue.h, which
unline all versions of the same file on Linux has the _FOREACH_SAFE
macros for iterating over a linked list.

The plugins are now in a TAILQ, loaded in alphabetic order and, unless
the dependency resolver says otherwise, added last in the queue.  So,
naming your plugins according to standard sysvinit rules: S01, S02,
etc. takes care of the most basic dependency resolution.  When that is
not sufficient, simply add a line ".depends = { "other_plugin",
"another_plugin" }," to your plugin_t definition.  Be careful though
for circular dependencies, we don't check for those.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2012-10-03 23:20:34 +02:00
1 parent 0d7d5a9820
commit 83a4bf7947
9 files changed
+728 -35

No files matched your search

+10 -4
View File
@@ -25,16 +25,17 @@
#define FINIT_PLUGIN_H_
#include <poll.h>
#include <sys/queue.h> /* BSD sys/queue.h API */
#include "queue.h" /* BSD sys/queue.h API */
#include "svc.h"
#define PLUGIN_DEP_MAX 10
#define PLUGIN_IO_READ POLLIN
#define PLUGIN_IO_WRITE POLLOUT
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void)
#define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void)
#define PLUGIN_ITERATOR(x) LIST_FOREACH(x, &plugins, link)
#define PLUGIN_ITERATOR(x, tmp) TAILQ_FOREACH_SAFE(x, &plugins, link, tmp)
/*
* Predefined hook points for easier plugin debugging
@@ -76,9 +77,9 @@ typedef enum {
*/
typedef struct plugin {
/* BSD sys/queue.h linked list node. */
LIST_ENTRY(plugin) link;
TAILQ_ENTRY(plugin) link;
/* Plugin name, defaults to plugin path if unset.
/* Plugin name, defaults to basename of plugin path if unset.
* NOTE: Must be same as @cmd for service plugins! */
char *name;
@@ -101,12 +102,17 @@ typedef struct plugin {
void *arg;
void (*cb)(void *arg, int fd, int events);
} io;
char *depends[PLUGIN_DEP_MAX]; /* List of other .name's this depends on. */
} plugin_t;
/* Public plugin API */
int plugin_register (plugin_t *plugin);
int plugin_unregister (plugin_t *plugin);
/* Helper API */
plugin_t *plugin_find (char *name);
#endif /* FINIT_PLUGIN_H_ */
/**