Initial conversion to use libuEv for all event handling.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2015-01-18 00:53:14 +01:00
parent 0669a9cb81
commit 425cd17e57
9 changed files with 91 additions and 127 deletions
+12 -8
View File
@@ -57,22 +57,24 @@ FINIT_RCSD ?= $(sysconfdir)/finit.d
CFLAGS += -W -Wall -Werror -Os
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
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 += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\"
CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\"
LDFLAGS += -rdynamic -L$(TOPDIR)/libite
DEPLIBS = libite/libite.so
DEPLIBS = libite/libite.so libuev/libuev.a
LDLIBS += -ldl -lite
include common.mk
export libdir plugindir incdir ROOTDIR CPPFLAGS LDFLAGS LDLIBS
all: $(DEPLIBS) $(EXEC)
$(MAKE) -C plugins $@
+$(MAKE) -C plugins $@
$(DEPLIBS): Makefile
$(MAKE) -C libite all
+$(MAKE) -C libite all
+$(MAKE) -C libuev all
$(OBJS): Makefile
@@ -133,13 +135,15 @@ uninstall: uninstall-exec uninstall-data uninstall-dev
clean:
-@$(RM) $(OBJS) $(DEPS) $(EXEC)
$(MAKE) -C libite $@
$(MAKE) -C plugins $@
+$(MAKE) -C plugins $@
+$(MAKE) -C libite $@
+$(MAKE) -C libuev $@
distclean: clean
-@$(RM) $(JUNK) unittest *.o .*.d
$(MAKE) -C libite $@
$(MAKE) -C plugins $@
+$(MAKE) -C plugins $@
+$(MAKE) -C libite $@
+$(MAKE) -C libuev $@
check:
$(CHECK) *.c plugins/*.c libite/*.c
+19 -21
View File
@@ -131,25 +131,12 @@ static int client(int argc, char *argv[])
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;
_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;
tty_runlevel(runlevel);
}
static void banner(void)
@@ -160,6 +147,9 @@ static void banner(void)
int main(int argc, char* argv[])
{
uev_t w;
uev_ctx_t ctx;
if (getpid() != 1)
return client(argc, argv);
@@ -173,6 +163,11 @@ int main(int argc, char* argv[])
*/
sig_init();
/*
* Initalize event context.
*/
uev_init(&ctx);
/*
* 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.
*/
print_desc("Loading plugins", NULL);
print_result(plugin_load_all(PLUGIN_PATH));
print_result(plugin_load_all(&ctx, PLUGIN_PATH));
/*
* Mount filesystems
@@ -232,7 +227,7 @@ int main(int argc, char* argv[])
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
/* Base FS up, enable standard SysV init signals */
sig_setup();
sig_setup(&ctx);
_d("Base FS up, calling hooks ...");
plugin_run_hooks(HOOK_BASEFS_UP);
@@ -279,10 +274,13 @@ int main(int argc, char* argv[])
/* Hooks that should run at the very end */
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
*/
return run_loop();
return uev_run(&ctx, 0);
}
/**
-3
View File
@@ -65,9 +65,6 @@
# define DEFHOST "noname"
#endif
/* Delay start of GETTY at boot. Must be > 0 */
#define DELAY_TTY 2
#define CMD_SIZE 256
#define LINE_SIZE 1024
#define BUF_SIZE 4096
+15 -57
View File
@@ -36,10 +36,8 @@
#define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0)
static char *plugpath = NULL; /* Set by first load. */
static size_t num_fds = 0;
static struct pollfd fds[MAX_NUM_FDS];
static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
static char *plugpath = NULL; /* Set by first load. */
static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
static void check_plugin_depends(plugin_t *plugin);
@@ -69,15 +67,8 @@ int plugin_register(plugin_t *plugin)
check_plugin_depends(plugin);
if (is_io_plugin(plugin)) {
if (num_fds + 1 >= MAX_NUM_FDS) {
num_fds = MAX_NUM_SVC;
errno = ENOMEM;
return 1;
}
num_fds++;
if (is_io_plugin(plugin))
inuse++;
}
if (plugin->svc.cb) {
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 */
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 */
PLUGIN_ITERATOR(p, tmp) {
if (is_io_plugin(p) && p->io.fd == io->fd) {
_d("Calling I/O %s from runloop...", basename(p->name));
p->io.cb(p->io.arg, io->fd, io->events);
if (is_io_plugin(p) && p->io.fd == w->fd) {
_d("Calling I/O %s from runloop...", basename(p->name));
p->io.cb(p->io.arg, w->fd, events);
/* Update fd, may be changed by plugin callback, e.g., if FIFO */
io->fd = p->io.fd;
io->events = 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;
/* Update fd, may be changed by plugin callback, e.g., if FIFO */
if (p->io.fd != w->fd)
uev_io_set (w, p->io.fd, p->io.flags);
}
}
/* 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_ITERATOR(p, tmp) {
if (is_io_plugin(p)) {
_d("Initializing plugin %s for I/O", basename(p->name));
fds[i].revents = 0;
fds[i].events = p->io.flags;
fds[i++].fd = p->io.fd;
uev_io_init(ctx, &p->watcher, generic_io_cb, p, p->io.fd, p->io.flags);
}
}
}
@@ -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;
DIR *dp = opendir(path);
@@ -341,7 +299,7 @@ int plugin_load_all(char *path)
}
closedir(dp);
init_plugins();
init_plugins(ctx);
return fail;
}
+6 -3
View File
@@ -24,13 +24,13 @@
#ifndef FINIT_PLUGIN_H_
#define FINIT_PLUGIN_H_
#include <poll.h>
#include "queue.h" /* BSD sys/queue.h API */
#include "svc.h"
#include "libuev/uev.h"
#define PLUGIN_DEP_MAX 10
#define PLUGIN_IO_READ POLLIN
#define PLUGIN_IO_WRITE POLLOUT
#define PLUGIN_IO_READ UEV_READ
#define PLUGIN_IO_WRITE UEV_WRITE
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) 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. */
TAILQ_ENTRY(plugin) link;
/* Event loop handler, used internally by Finit */
uev_t watcher;
/* Plugin name, defaults to basename of plugin path if unset.
* NOTE: Must be same as @cmd for service plugins! */
char *name;
+2 -3
View File
@@ -29,11 +29,10 @@
#include "plugin.h"
void svc_bootstrap (void);
void svc_monitor (void);
void svc_monitor (pid_t lost);
void plugin_run_hooks (hook_point_t no);
int plugin_load_all (char *path);
void plugin_monitor (void);
int plugin_load_all (uev_ctx_t *ctx, char *path);
#endif /* FINIT_PRIVATE_H_ */
+34 -25
View File
@@ -47,9 +47,13 @@
#include "private.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);
@@ -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)",
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
do_shutdown(sig);
do_shutdown(w->signo);
}
/*
* 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);
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;
erase(SYNC_STOPPED);
}
@@ -131,6 +132,11 @@ int sig_stopped(void)
/*
* 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)
{
int i;
@@ -145,7 +151,7 @@ void sig_init(void)
/*
* Setup limited set of SysV compatible signals to respond to
*/
void sig_setup(void)
void sig_setup(uev_ctx_t *ctx)
{
struct sigaction sa;
@@ -156,12 +162,12 @@ void sig_setup(void)
erase(SYNC_STOPPED);
/* Standard SysV init calls ctrl-alt-delete handler */
SETSIG(sa, SIGINT, shutdown_handler, 0);
SETSIG(sa, SIGPWR, shutdown_handler, 0);
uev_signal_init(ctx, &sigint_watcher, sigint_cb, NULL, SIGINT);
uev_signal_init(ctx, &sigpwr_watcher, sigint_cb, NULL, SIGPWR);
/* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */
// SETSIG2(sa, SIGUSR1, reopen_initctl, 0);
// SETSIG2(sa, SIGUSR2, pwrdwn_handler, 0);
// uev_signal_init(&ctx, &sigusr1_watcher, reopen_initctl_cb, NULL, SIGUSR1);
// uev_signal_init(&ctx, &sigusr2_watcher, pwrdwn_cb, NULL, SIGUSR2);
/* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */
IGNSIG(sa, SIGTERM, 0);
@@ -172,10 +178,13 @@ void sig_setup(void)
/* We don't have any /etc/inittab yet, reread finit.conf? */
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. */
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
SETSIG(sa, SIGCONT, sigcont_handler, 0);
uev_signal_init(ctx, &sigstop_watcher, sigstop_cb, NULL, SIGSTOP);
uev_signal_init(ctx, &sigtstp_watcher, sigstop_cb, NULL, SIGTSTP);
uev_signal_init(ctx, &sigcont_watcher, sigcont_cb, NULL, SIGCONT);
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
reboot(RB_DISABLE_CAD);
+2 -1
View File
@@ -26,6 +26,7 @@
#define FINIT_SIG_H_
#include <signal.h>
#include "libuev/uev.h"
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
#define SYNC_STOPPED "/var/lock/finit.stopped"
@@ -57,7 +58,7 @@
void do_shutdown (int sig);
int sig_stopped (void);
void sig_init (void);
void sig_setup (void);
void sig_setup (uev_ctx_t *ctx);
#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;
if (was_stopped && !is_norespawn()) {
@@ -373,10 +372,6 @@ void svc_monitor(void)
return;
}
lost = waitpid(-1, NULL, WNOHANG);
if (lost < 1)
return;
if (fexist(SYNC_SHUTDOWN) || lost <= 1)
return;