diff --git a/plugin.c b/plugin.c index faa7896c..fd497d1d 100644 --- a/plugin.c +++ b/plugin.c @@ -32,7 +32,6 @@ #include "private.h" #include "helpers.h" #include "plugin.h" -#include "svc.h" #define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0) @@ -69,11 +68,13 @@ int plugin_register(plugin_t *plugin) } if (plugin->svc.cb) { - svc_t *svc = svc_find_by_name(plugin->name); + svc_t *svc = svc_find(plugin->name); if (svc) { - plugin->svc.id = svc_id(svc); inuse++; + svc->cb = plugin->svc.cb; + svc->dynamic = plugin->svc.dynamic; + svc->dynamic_stop = plugin->svc.dynamic_stop; } } @@ -91,6 +92,15 @@ int plugin_unregister(plugin_t *plugin) { LIST_REMOVE(plugin, link); + if (plugin->svc.cb) { + svc_t *svc = svc_find(plugin->name); + + if (svc) { + svc->cb = NULL; + svc->dynamic = 0; + } + } + /* XXX: Unfinished, add cleanup code here! */ return 0; @@ -109,21 +119,6 @@ void plugin_run_hooks(hook_point_t no) } } -/* Run registered plugin service callback for the given svc ID */ -svc_cmd_t plugin_svc_enabled(svc_t *svc, int event, void *arg) -{ - plugin_t *p; - - /* Find matching plugin, pick first matching fd */ - PLUGIN_ITERATOR(p) { - if (p->svc.id == svc_id(svc)) - return p->svc.cb(svc, event, arg); - } - - /* Unknown service, default to start (since it's in finit.conf) */ - return SVC_START; -} - /* Generic libev I/O callback, looks up correct plugin and calls its callback */ static void generic_io_cb(int fd, int events) { diff --git a/plugin.h b/plugin.h index 57e045d7..235e55a8 100644 --- a/plugin.h +++ b/plugin.h @@ -83,11 +83,8 @@ typedef struct plugin { /* Service callback to be called once per lap of runloop. */ struct { - /* Private */ - int id; /* Service ID# to match this service plugin against, set on installation. */ - - /* Public */ - int dynamic; /* Reload (SIGHUP) on dynamic event? Set by plugin. */ + int dynamic; /* Callback wants external events as well. */ + int dynamic_stop; /* Callback allows dynamic events to stop. */ svc_cmd_t (*cb)(svc_t *svc, int event, void *event_arg); } svc; diff --git a/private.h b/private.h index bdbb87f7..49558eb0 100644 --- a/private.h +++ b/private.h @@ -28,13 +28,12 @@ #include "svc.h" #include "plugin.h" -void svc_start_all (void); -void svc_monitor (void); +void svc_start_all (void); +void svc_monitor (void); -void plugin_run_hooks (hook_point_t no); -svc_cmd_t plugin_svc_enabled (svc_t *svc, int event, void *arg); -int plugin_load_all (char *path); -void plugin_monitor (void); +void plugin_run_hooks (hook_point_t no); +int plugin_load_all (char *path); +void plugin_monitor (void); #endif /* FINIT_PRIVATE_H_ */ diff --git a/svc.c b/svc.c index 8b2da1b8..eb014834 100644 --- a/svc.c +++ b/svc.c @@ -66,7 +66,6 @@ svc_t *svc_new(void) if (svc_counter < MAX_NUM_SVC) { svc = &services[svc_counter++]; memset(svc, 0, sizeof(*svc)); - svc->id = svc_counter; /* Array pos + 1 to avoid zero ID */ } else { errno = ENOMEM; return NULL; @@ -76,29 +75,13 @@ svc_t *svc_new(void) } /** - * svc_find_by_id - Find a service object by its logical ID# - * @id: Logical ID# - * - * Returns: - * A pointer to an &svc_t object, or %NULL if not found. - */ -svc_t *svc_find_by_id(int id) -{ - __connect_shm(); - if (id < 1 || id > svc_counter) - return NULL; - - return &services[id - 1]; -} - -/** - * svc_find_by_name - Find a service object by its full path name + * svc_find - Find a service object by its full path name * @name: Full path name, e.g., /sbin/syslogd * * Returns: * A pointer to an &svc_t object, or %NULL if not found. */ -svc_t *svc_find_by_name(char *name) +svc_t *svc_find(char *name) { int i; @@ -226,7 +209,12 @@ svc_cmd_t svc_enabled(svc_t *svc, int event, void *arg) return SVC_STOP; } - return plugin_svc_enabled(svc, event, arg); + /* Is there a service plugin registered? */ + if (svc->cb) + return svc->cb(svc, event, arg); + + /* No service plugin, default to start, since listed in finit.conf */ + return SVC_START; } static int is_norespawn(void) @@ -335,7 +323,7 @@ int svc_start(svc_t *svc) int svc_start_by_name(char *name) { - svc_t *svc = svc_find_by_name(name); + svc_t *svc = svc_find(name); if (svc && svc_enabled(svc, 0, NULL)) return svc_start(svc); @@ -369,6 +357,10 @@ int svc_stop(svc_t *svc) int svc_reload(svc_t *svc) { + /* Ignore if finit is SIGSTOP'ed */ + if (is_norespawn()) + return 0; + if (!svc) { _e("Failed, no svc pointer."); return 1; diff --git a/svc.h b/svc.h index 45499758..68c73114 100644 --- a/svc.h +++ b/svc.h @@ -48,17 +48,22 @@ typedef enum { * of issuing an initctl call. E.g. * initctl service */ typedef struct svc { - /* Private */ - int id; /* Service ID#, set by svc_new() */ pid_t pid; + int reload; char cmd[MAX_ARG_LEN]; char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN]; char desc[MAX_STR_LEN]; char username[MAX_USER_LEN]; - /* Public */ - int reload; /* For external plugins. */ - int private; /* For callbacks to use freely, possibly to store "states", set by plugin. */ + /* For external plugins. If @cb is set a plugin is loaded. + * @dynamic: Set by plugins that want dynamic events. + * @dynamic_stop: Set by plugins that allow dyn. events to stop it as well. + * @private: Can be used freely by plugin, e.g., to store "states". + */ + int dynamic; + int dynamic_stop; + int private; + svc_cmd_t (*cb)(struct svc *svc, int event, void *event_arg); } svc_t; typedef struct svc_map svc_map_t; @@ -78,19 +83,8 @@ static inline svc_t *finit_svc_connect(void) return (svc_t *)ptr; } -static inline int svc_id(svc_t *svc) -{ - if (!svc) { - errno = EINVAL; - return -1; - } - - return svc->id; -} - svc_t *svc_new (void); -svc_t *svc_find_by_id (int id); -svc_t *svc_find_by_name (char *name); +svc_t *svc_find (char *name); svc_t *svc_iterator (int restart); int svc_register (char *line, char *username);