diff --git a/plugins/pidfile.c b/plugins/pidfile.c index cad82fb9..5bbabb76 100644 --- a/plugins/pidfile.c +++ b/plugins/pidfile.c @@ -114,7 +114,7 @@ static void pidfile_reconf(void *_null) } if (restart) - service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); + service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_RUNTASK | SVC_TYPE_INETD); } while (restart); } diff --git a/src/plugin.c b/src/plugin.c index 761999b2..777d1b2c 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -30,10 +30,12 @@ #include /* BSD sys/queue.h API */ #include "config.h" +#include "cond.h" #include "finit.h" -#include "private.h" #include "helpers.h" #include "plugin.h" +#include "private.h" +#include "service.h" #define is_io_plugin(p) ((p)->io.cb && (p)->io.fd > 0) #define SEARCH_PLUGIN(str) \ @@ -163,6 +165,15 @@ plugin_t *plugin_find(char *name) } /* Private daemon API *******************************************************/ +#define CHOOSE(x, y) y +static const char *hook_cond[] = HOOK_TYPES; +#undef CHOOSE + +const char *plugin_hook_str(hook_point_t no) +{ + return hook_cond[no]; +} + int plugin_exists(hook_point_t no) { plugin_t *p, *tmp; @@ -178,14 +189,34 @@ int plugin_exists(hook_point_t no) /* Some hooks are called with a fixed argument, like HOOK_SVC_LOST */ void plugin_run_hook(hook_point_t no, void *arg) { + static int last = -1; plugin_t *p, *tmp; + /* + * End recursion: any plugin hook => start service => SVC start + * hook => start service ... err ... wait a second + */ + if (HOOK_SVC_START == last) { + _d("End plugin recursion in our lifetime!"); + return; + } + PLUGIN_ITERATOR(p, tmp) { if (p->hook[no].cb) { _d("Calling %s hook n:o %d (arg: %p) ...", basename(p->name), no, arg); p->hook[no].cb(arg ? arg : p->hook[no].arg); } } + + /* Guard against infinite recursion */ + if (HOOK_SVC_START == no) + last = no; + + cond_set(hook_cond[no]); + service_step_all(SVC_TYPE_RUNTASK); + + if (HOOK_SVC_START == no) + last = -1; } /* Regular hooks are called with the registered plugin's argument */ diff --git a/src/plugin.h b/src/plugin.h index 9f86bb7e..b9d60a0b 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -51,28 +51,34 @@ #define PLUGIN_ITERATOR(x, tmp) TAILQ_FOREACH_SAFE(x, &plugins, link, tmp) /* - * Predefined hook points for easier plugin debugging + * Predefined hook points and corresponding conditions in Finit, + * for use by plugins and scripts. Recommended to use the task + * or run stanzas: task /bin/rescue.sh */ -typedef enum { - /* Bootstrap hooks */ - HOOK_BANNER = 0, - HOOK_ROOTFS_UP, - HOOK_MOUNT_ERROR, - HOOK_BASEFS_UP, - HOOK_NETWORK_UP, - HOOK_SVC_UP, - HOOK_SYSTEM_UP, +#define HOOK_TYPES { \ + /* Bootstrap hooks, runlevel [S] */ \ + CHOOSE(HOOK_BANNER = 0, "hook/sys/banner"), \ + CHOOSE(HOOK_ROOTFS_UP, "hook/mount/root"), \ + CHOOSE(HOOK_MOUNT_ERROR, "hook/mount/error"), \ + CHOOSE(HOOK_BASEFS_UP, "hook/mount/all"), \ + CHOOSE(HOOK_NETWORK_UP, "hook/net/up"), \ + CHOOSE(HOOK_SVC_UP, "hook/svc/up"), \ + CHOOSE(HOOK_SYSTEM_UP, "hook/sys/up"), \ + \ + /* Runtime hooks, runlevel [S1-9] */ \ + CHOOSE(HOOK_SVC_RECONF, "hook/svc/reconf"), \ + CHOOSE(HOOK_SVC_LOST, "hook/svc/lost"), \ + CHOOSE(HOOK_SVC_START, "hook/svc/start"), \ + CHOOSE(HOOK_RUNLEVEL_CHANGE, "hook/sys/runlevel"), \ + \ + /* Shutdown hooks, runlevel [06] */ \ + CHOOSE(HOOK_SHUTDOWN, "hook/sys/shutdown"), \ + CHOOSE(HOOK_MAX_NUM, "nop") \ +} - /* Runtime hooks */ - HOOK_SVC_RECONF, - HOOK_SVC_LOST, - HOOK_SVC_START, - HOOK_RUNLEVEL_CHANGE, - - /* Shutdown hooks */ - HOOK_SHUTDOWN, - HOOK_MAX_NUM -} hook_point_t; +#define CHOOSE(x, y) x +typedef enum HOOK_TYPES hook_point_t; +#undef CHOOSE /** * plugin_t - Finit &plugin_t object diff --git a/src/private.h b/src/private.h index e11b3e2c..53c9659e 100644 --- a/src/private.h +++ b/src/private.h @@ -40,6 +40,7 @@ int client (int argc, char *argv[]); void service_monitor (pid_t lost); +const char *plugin_hook_str(hook_point_t no); int plugin_exists (hook_point_t no); void plugin_run_hook (hook_point_t no, void *arg); void plugin_run_hooks (hook_point_t no);