mirror of
https://github.com/troglobit/finit.git
synced 2026-10-06 07:43:43 +07:00
Greatly simplify svc hook for external plugins
This commit removes a lot of unnecessary overhead for handling external service plugins. Instead of traversing the plugin array every time a service callback should run we set the plugin callback in the svc_t when the plugin is registered. Also, make sure to check for norespawn/SIGSTOP in svc_reload() as well. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -48,17 +48,22 @@ typedef enum {
|
||||
* of issuing an initctl call. E.g.
|
||||
* initctl <stop|start|restart> 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);
|
||||
|
||||
Reference in New Issue
Block a user