Initial conversion to use libuEv for all event handling.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2015-01-18 00:53:14 +01:00
1 parent 0669a9cb81
commit 425cd17e57
9 files changed
+91 -127

No files matched your search

+12 -8
View File
@@ -57,22 +57,24 @@ FINIT_RCSD ?= $(sysconfdir)/finit.d
CFLAGS += -W -Wall -Werror -Os CFLAGS += -W -Wall -Werror -Os
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997 # Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
CPPFLAGS += -U_FORTIFY_SOURCE CPPFLAGS += -U_FORTIFY_SOURCE
CPPFLAGS += -Ilibite -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE CPPFLAGS += -Ilibite -Ilibuev
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\" CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
CPPFLAGS += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\" CPPFLAGS += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\"
CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\" CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\"
LDFLAGS += -rdynamic -L$(TOPDIR)/libite LDFLAGS += -rdynamic -L$(TOPDIR)/libite
DEPLIBS = libite/libite.so DEPLIBS = libite/libite.so libuev/libuev.a
LDLIBS += -ldl -lite LDLIBS += -ldl -lite
include common.mk include common.mk
export libdir plugindir incdir ROOTDIR CPPFLAGS LDFLAGS LDLIBS export libdir plugindir incdir ROOTDIR CPPFLAGS LDFLAGS LDLIBS
all: $(DEPLIBS) $(EXEC) all: $(DEPLIBS) $(EXEC)
$(MAKE) -C plugins $@ +$(MAKE) -C plugins $@
$(DEPLIBS): Makefile $(DEPLIBS): Makefile
$(MAKE) -C libite all +$(MAKE) -C libite all
+$(MAKE) -C libuev all
$(OBJS): Makefile $(OBJS): Makefile
@@ -133,13 +135,15 @@ uninstall: uninstall-exec uninstall-data uninstall-dev
clean: clean:
-@$(RM) $(OBJS) $(DEPS) $(EXEC) -@$(RM) $(OBJS) $(DEPS) $(EXEC)
$(MAKE) -C libite $@ +$(MAKE) -C plugins $@
$(MAKE) -C plugins $@ +$(MAKE) -C libite $@
+$(MAKE) -C libuev $@
distclean: clean distclean: clean
-@$(RM) $(JUNK) unittest *.o .*.d -@$(RM) $(JUNK) unittest *.o .*.d
$(MAKE) -C libite $@ +$(MAKE) -C plugins $@
$(MAKE) -C plugins $@ +$(MAKE) -C libite $@
+$(MAKE) -C libuev $@
check: check:
$(CHECK) *.c plugins/*.c libite/*.c $(CHECK) *.c plugins/*.c libite/*.c
+19 -21
View File
@@ -131,25 +131,12 @@ static int client(int argc, char *argv[])
return 0; return 0;
} }
static int run_loop(void) /*
* Delayed start of TTYs to let the system stabilize at boot
*/
static void delayed_tty_start(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
{ {
int delay = DELAY_TTY ?: 1; tty_runlevel(runlevel);
_d("Entering main loop ...");
while (1) {
svc_monitor();
plugin_monitor();
/* Delayed start of TTYs to let the system stabilize
* after switching runlevels. */
if (delay) {
if (--delay == 0)
tty_runlevel(runlevel);
continue;
}
}
return 0;
} }
static void banner(void) static void banner(void)
@@ -160,6 +147,9 @@ static void banner(void)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
uev_t w;
uev_ctx_t ctx;
if (getpid() != 1) if (getpid() != 1)
return client(argc, argv); return client(argc, argv);
@@ -173,6 +163,11 @@ int main(int argc, char* argv[])
*/ */
sig_init(); sig_init();
/*
* Initalize event context.
*/
uev_init(&ctx);
/* /*
* Mount base file system, kernel is assumed to run devtmpfs for /dev * Mount base file system, kernel is assumed to run devtmpfs for /dev
*/ */
@@ -208,7 +203,7 @@ int main(int argc, char* argv[])
* hook on to. * hook on to.
*/ */
print_desc("Loading plugins", NULL); print_desc("Loading plugins", NULL);
print_result(plugin_load_all(PLUGIN_PATH)); print_result(plugin_load_all(&ctx, PLUGIN_PATH));
/* /*
* Mount filesystems * Mount filesystems
@@ -232,7 +227,7 @@ int main(int argc, char* argv[])
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories"); run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
/* Base FS up, enable standard SysV init signals */ /* Base FS up, enable standard SysV init signals */
sig_setup(); sig_setup(&ctx);
_d("Base FS up, calling hooks ..."); _d("Base FS up, calling hooks ...");
plugin_run_hooks(HOOK_BASEFS_UP); plugin_run_hooks(HOOK_BASEFS_UP);
@@ -279,10 +274,13 @@ int main(int argc, char* argv[])
/* Hooks that should run at the very end */ /* Hooks that should run at the very end */
plugin_run_hooks(HOOK_SYSTEM_UP); plugin_run_hooks(HOOK_SYSTEM_UP);
/* Delayed start of TTY's at boot (one-shot timer) */
uev_timer_init(&ctx, &w, delayed_tty_start, NULL, 2000, 0);
/* /*
* Enter main loop to monior /dev/initctl and services * Enter main loop to monior /dev/initctl and services
*/ */
return run_loop(); return uev_run(&ctx, 0);
} }
/** /**
-3
View File
@@ -65,9 +65,6 @@
# define DEFHOST "noname" # define DEFHOST "noname"
#endif #endif
/* Delay start of GETTY at boot. Must be > 0 */
#define DELAY_TTY 2
#define CMD_SIZE 256 #define CMD_SIZE 256
#define LINE_SIZE 1024 #define LINE_SIZE 1024
#define BUF_SIZE 4096 #define BUF_SIZE 4096
+15 -57
View File
@@ -36,10 +36,8 @@
#define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0) #define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0)
static char *plugpath = NULL; /* Set by first load. */ static char *plugpath = NULL; /* Set by first load. */
static size_t num_fds = 0; static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
static struct pollfd fds[MAX_NUM_FDS];
static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
static void check_plugin_depends(plugin_t *plugin); static void check_plugin_depends(plugin_t *plugin);
@@ -69,15 +67,8 @@ int plugin_register(plugin_t *plugin)
check_plugin_depends(plugin); check_plugin_depends(plugin);
if (is_io_plugin(plugin)) { if (is_io_plugin(plugin))
if (num_fds + 1 >= MAX_NUM_FDS) {
num_fds = MAX_NUM_SVC;
errno = ENOMEM;
return 1;
}
num_fds++;
inuse++; inuse++;
}
if (plugin->svc.cb) { if (plugin->svc.cb) {
svc_t *svc = svc_find(plugin->name); svc_t *svc = svc_find(plugin->name);
@@ -189,62 +180,29 @@ void plugin_run_hooks(hook_point_t no)
} }
/* Generic libev I/O callback, looks up correct plugin and calls its callback */ /* Generic libev I/O callback, looks up correct plugin and calls its callback */
static void generic_io_cb(struct pollfd *io) static void generic_io_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *arg, int events)
{ {
plugin_t *p, *tmp; plugin_t *p = (plugin_t *)arg;
/* Find matching plugin, pick first matching fd */ if (is_io_plugin(p) && p->io.fd == w->fd) {
PLUGIN_ITERATOR(p, tmp) { _d("Calling I/O %s from runloop...", basename(p->name));
if (is_io_plugin(p) && p->io.fd == io->fd) { p->io.cb(p->io.arg, w->fd, events);
_d("Calling I/O %s from runloop...", basename(p->name));
p->io.cb(p->io.arg, io->fd, io->events);
/* Update fd, may be changed by plugin callback, e.g., if FIFO */ /* Update fd, may be changed by plugin callback, e.g., if FIFO */
io->fd = p->io.fd; if (p->io.fd != w->fd)
io->events = p->io.flags; uev_io_set (w, p->io.fd, p->io.flags);
io->revents = 0;
break;
}
}
}
void plugin_monitor(void)
{
int ret;
size_t i;
while ((ret = poll(fds, num_fds, 500))) {
if (-1 == ret) {
if (EINTR == errno)
continue;
_e("Failed polling I/O plugin descriptors, error %d: %s",
errno, strerror(errno));
break;
}
/* Traverse all I/O fds and run callbacks */
for (i = 0; i < num_fds; i++) {
if (fds[i].revents)
generic_io_cb(&fds[i]);
}
break;
} }
} }
/* Setup any I/O callbacks for plugins that use them */ /* Setup any I/O callbacks for plugins that use them */
static void init_plugins(void) static void init_plugins(uev_ctx_t *ctx)
{ {
int i = 0;
plugin_t *p, *tmp; plugin_t *p, *tmp;
PLUGIN_ITERATOR(p, tmp) { PLUGIN_ITERATOR(p, tmp) {
if (is_io_plugin(p)) { if (is_io_plugin(p)) {
_d("Initializing plugin %s for I/O", basename(p->name)); _d("Initializing plugin %s for I/O", basename(p->name));
fds[i].revents = 0; uev_io_init(ctx, &p->watcher, generic_io_cb, p, p->io.fd, p->io.flags);
fds[i].events = p->io.flags;
fds[i++].fd = p->io.fd;
} }
} }
} }
@@ -318,7 +276,7 @@ static void check_plugin_depends(plugin_t *plugin)
} }
} }
int plugin_load_all(char *path) int plugin_load_all(uev_ctx_t *ctx, char *path)
{ {
int fail = 0; int fail = 0;
DIR *dp = opendir(path); DIR *dp = opendir(path);
@@ -341,7 +299,7 @@ int plugin_load_all(char *path)
} }
closedir(dp); closedir(dp);
init_plugins(); init_plugins(ctx);
return fail; return fail;
} }
+6 -3
View File
@@ -24,13 +24,13 @@
#ifndef FINIT_PLUGIN_H_ #ifndef FINIT_PLUGIN_H_
#define FINIT_PLUGIN_H_ #define FINIT_PLUGIN_H_
#include <poll.h>
#include "queue.h" /* BSD sys/queue.h API */ #include "queue.h" /* BSD sys/queue.h API */
#include "svc.h" #include "svc.h"
#include "libuev/uev.h"
#define PLUGIN_DEP_MAX 10 #define PLUGIN_DEP_MAX 10
#define PLUGIN_IO_READ POLLIN #define PLUGIN_IO_READ UEV_READ
#define PLUGIN_IO_WRITE POLLOUT #define PLUGIN_IO_WRITE UEV_WRITE
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void) #define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void)
#define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void) #define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void)
@@ -79,6 +79,9 @@ typedef struct plugin {
/* BSD sys/queue.h linked list node. */ /* BSD sys/queue.h linked list node. */
TAILQ_ENTRY(plugin) link; TAILQ_ENTRY(plugin) link;
/* Event loop handler, used internally by Finit */
uev_t watcher;
/* Plugin name, defaults to basename of plugin path if unset. /* Plugin name, defaults to basename of plugin path if unset.
* NOTE: Must be same as @cmd for service plugins! */ * NOTE: Must be same as @cmd for service plugins! */
char *name; char *name;
+2 -3
View File
@@ -29,11 +29,10 @@
#include "plugin.h" #include "plugin.h"
void svc_bootstrap (void); void svc_bootstrap (void);
void svc_monitor (void); void svc_monitor (pid_t lost);
void plugin_run_hooks (hook_point_t no); void plugin_run_hooks (hook_point_t no);
int plugin_load_all (char *path); int plugin_load_all (uev_ctx_t *ctx, char *path);
void plugin_monitor (void);
#endif /* FINIT_PRIVATE_H_ */ #endif /* FINIT_PRIVATE_H_ */
+34 -25
View File
@@ -47,9 +47,13 @@
#include "private.h" #include "private.h"
#include "sig.h" #include "sig.h"
static int stopped = 0; static int stopped = 0;
static uev_t sigint_watcher, sigpwr_watcher;
static uev_t sigchld_watcher;
static uev_t sigstop_watcher, sigtstp_watcher, sigcont_watcher;
void do_shutdown (int sig)
void do_shutdown(int sig)
{ {
touch(SYNC_SHUTDOWN); touch(SYNC_SHUTDOWN);
@@ -84,38 +88,35 @@ void do_shutdown (int sig)
} }
/* /*
* Shut down on INT USR1 USR2 * Shut down on INT PWR
*/ */
static void shutdown_handler(int sig, siginfo_t *info, void *UNUSED(ctx)) static void sigint_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *UNUSED(arg), int UNUSED(events))
{ {
_d("Rebooting on signal %d from %s (PID %d)", do_shutdown(w->signo);
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
do_shutdown(sig);
} }
/* /*
* SIGCHLD: one of our children has died * SIGCHLD: one of our children has died
*/ */
static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(ctx)) static void sigchld_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
{ {
/* Do nothing, the svc_monitor() is the designated child reaper. */ svc_monitor(waitpid(-1, NULL, WNOHANG));
} }
/* /*
* SIGSTOP: Paused by user or netflash * SIGSTOP/SIGTSTP: Paused by user or netflash
*/ */
static void sigstop_handler(int sig, siginfo_t *info, void *UNUSED(ctx)) static void sigstop_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
{ {
_d("Received SIGSTOP(%d) from %s (PID %d)",
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
touch(SYNC_STOPPED); touch(SYNC_STOPPED);
stopped++; stopped++;
} }
static void sigcont_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
/*
* SIGCONT: Restart service monitor
*/
static void sigcont_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
{ {
_d("Received SIGCONT(%d) from %s (PID %d)",
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
stopped = 0; stopped = 0;
erase(SYNC_STOPPED); erase(SYNC_STOPPED);
} }
@@ -131,6 +132,11 @@ int sig_stopped(void)
/* /*
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding * Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
*/ */
static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(ctx))
{
/* NOP */
}
void sig_init(void) void sig_init(void)
{ {
int i; int i;
@@ -145,7 +151,7 @@ void sig_init(void)
/* /*
* Setup limited set of SysV compatible signals to respond to * Setup limited set of SysV compatible signals to respond to
*/ */
void sig_setup(void) void sig_setup(uev_ctx_t *ctx)
{ {
struct sigaction sa; struct sigaction sa;
@@ -156,12 +162,12 @@ void sig_setup(void)
erase(SYNC_STOPPED); erase(SYNC_STOPPED);
/* Standard SysV init calls ctrl-alt-delete handler */ /* Standard SysV init calls ctrl-alt-delete handler */
SETSIG(sa, SIGINT, shutdown_handler, 0); uev_signal_init(ctx, &sigint_watcher, sigint_cb, NULL, SIGINT);
SETSIG(sa, SIGPWR, shutdown_handler, 0); uev_signal_init(ctx, &sigpwr_watcher, sigint_cb, NULL, SIGPWR);
/* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */ /* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */
// SETSIG2(sa, SIGUSR1, reopen_initctl, 0); // uev_signal_init(&ctx, &sigusr1_watcher, reopen_initctl_cb, NULL, SIGUSR1);
// SETSIG2(sa, SIGUSR2, pwrdwn_handler, 0); // uev_signal_init(&ctx, &sigusr2_watcher, pwrdwn_cb, NULL, SIGUSR2);
/* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */ /* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */
IGNSIG(sa, SIGTERM, 0); IGNSIG(sa, SIGTERM, 0);
@@ -172,10 +178,13 @@ void sig_setup(void)
/* We don't have any /etc/inittab yet, reread finit.conf? */ /* We don't have any /etc/inittab yet, reread finit.conf? */
IGNSIG(sa, SIGHUP, 0); IGNSIG(sa, SIGHUP, 0);
/* After initial bootstrap of Finit we call the service monitor to reap children */
uev_signal_init(ctx, &sigchld_watcher, sigchld_cb, NULL, SIGCHLD);
/* Stopping init is a bit tricky. */ /* Stopping init is a bit tricky. */
SETSIG(sa, SIGSTOP, sigstop_handler, 0); uev_signal_init(ctx, &sigstop_watcher, sigstop_cb, NULL, SIGSTOP);
SETSIG(sa, SIGTSTP, sigstop_handler, 0); uev_signal_init(ctx, &sigtstp_watcher, sigstop_cb, NULL, SIGTSTP);
SETSIG(sa, SIGCONT, sigcont_handler, 0); uev_signal_init(ctx, &sigcont_watcher, sigcont_cb, NULL, SIGCONT);
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */ /* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
reboot(RB_DISABLE_CAD); reboot(RB_DISABLE_CAD);
+2 -1
View File
@@ -26,6 +26,7 @@
#define FINIT_SIG_H_ #define FINIT_SIG_H_
#include <signal.h> #include <signal.h>
#include "libuev/uev.h"
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown" #define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
#define SYNC_STOPPED "/var/lock/finit.stopped" #define SYNC_STOPPED "/var/lock/finit.stopped"
@@ -57,7 +58,7 @@
void do_shutdown (int sig); void do_shutdown (int sig);
int sig_stopped (void); int sig_stopped (void);
void sig_init (void); void sig_init (void);
void sig_setup (void); void sig_setup (uev_ctx_t *ctx);
#endif /* FINIT_SIG_H_ */ #endif /* FINIT_SIG_H_ */
+1 -6
View File
@@ -362,9 +362,8 @@ static void restart_any_lost_procs(void)
} }
} }
void svc_monitor(void) void svc_monitor(pid_t lost)
{ {
pid_t lost;
svc_t *svc; svc_t *svc;
if (was_stopped && !is_norespawn()) { if (was_stopped && !is_norespawn()) {
@@ -373,10 +372,6 @@ void svc_monitor(void)
return; return;
} }
lost = waitpid(-1, NULL, WNOHANG);
if (lost < 1)
return;
if (fexist(SYNC_SHUTDOWN) || lost <= 1) if (fexist(SYNC_SHUTDOWN) || lost <= 1)
return; return;