From: Hitoshi Mitake <[email protected]> Current DynamoRIO doesn't support timerfd and signalfd, so this patch let sheepdog stop using them. This is a temporal, adhoc stuff.
Signed-off-by: Hitoshi Mitake <[email protected]> --- collie/Makefile.am | 2 +- include/event.h | 2 + lib/event.c | 109 ++++++++++++++++++++++++++++++++++++++++++++----- sheep/Makefile.am | 2 +- sheep/cluster/local.c | 35 ++++++++++----- sheep/sheep.c | 35 +++++++++++----- shepherd/Makefile.am | 2 +- 7 files changed, 151 insertions(+), 36 deletions(-) diff --git a/collie/Makefile.am b/collie/Makefile.am index 386aa49..4b253f2 100644 --- a/collie/Makefile.am +++ b/collie/Makefile.am @@ -30,7 +30,7 @@ collie_SOURCES += debug.c override CFLAGS := $(subst -pg -gstabs,,$(CFLAGS)) endif -collie_LDADD = ../lib/libsheepdog.a +collie_LDADD = ../lib/libsheepdog.a -lrt collie_DEPENDENCIES = ../lib/libsheepdog.a noinst_HEADERS = treeview.h collie.h diff --git a/include/event.h b/include/event.h index 65277fa..de401ff 100644 --- a/include/event.h +++ b/include/event.h @@ -32,4 +32,6 @@ static inline int register_event(int fd, event_handler_t h, void *data) return register_event_prio(fd, h, data, EVENT_PRIO_DEFAULT); } +void init_timer(void); + #endif diff --git a/lib/event.c b/lib/event.c index 5b15925..68ec5c3 100644 --- a/lib/event.c +++ b/lib/event.c @@ -14,7 +14,8 @@ #include <string.h> #include <unistd.h> #include <sys/epoll.h> -#include <sys/timerfd.h> +#include <signal.h> +#include <time.h> #include "list.h" #include "util.h" @@ -26,42 +27,128 @@ static LIST_HEAD(events_list); #define TICK 1 +struct timer_desc { + int pipe[2]; + unsigned int msec; + + timer_t timerid; + struct timer *t; + + struct list_head list; +}; + +static LIST_HEAD(timer_list); + static void timer_handler(int fd, int events, void *data) { - struct timer *t = data; + struct timer_desc *desc = data; + struct timer *t = desc->t; uint64_t val; + assert(fd == desc->pipe[0]); + if (read(fd, &val, sizeof(val)) < 0) return; t->callback(t->data); + timer_delete(desc->timerid); + list_del(&desc->list); + unregister_event(fd); - close(fd); + close(desc->pipe[0]); + close(desc->pipe[1]); + + free(desc); +} + +static void insert_timer_desc(struct timer_desc *t) +{ + struct timer_desc *p; + struct list_head *pred; + + pred = NULL; + + list_for_each_entry(p, &timer_list, list) { + if (p->msec < t->msec) + continue; + + pred = &p->list; + break; + } + + if (!pred) + pred = &timer_list; + + list_add(&t->list, pred); } void add_timer(struct timer *t, unsigned int mseconds) { + int ret; + struct timer_desc *desc; struct itimerspec it; - int tfd; - tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); - if (tfd < 0) { - sd_eprintf("timerfd_create: %m"); - return; + desc = xzalloc(sizeof(*desc)); + desc->msec = mseconds; + INIT_LIST_HEAD(&desc->list); + + ret = timer_create(CLOCK_MONOTONIC, NULL, &desc->timerid); + if (ret < 0) { + sd_eprintf("timer_create: %m"); + goto free_timer_desc; } memset(&it, 0, sizeof(it)); it.it_value.tv_sec = mseconds / 1000; it.it_value.tv_nsec = (mseconds % 1000) * 1000000; - if (timerfd_settime(tfd, 0, &it, NULL) < 0) { + if (timer_settime(desc->timerid, 0, &it, NULL) < 0) { sd_eprintf("timerfd_settime: %m"); - return; + goto del_timer; + } + + ret = pipe(desc->pipe); + if (ret < 0) { + sd_eprintf("pipe: %m"); + goto del_timer; } - if (register_event(tfd, timer_handler, t) < 0) + if (register_event(desc->pipe[0], timer_handler, desc) < 0) { sd_eprintf("failed to register timer fd"); + goto close_pipe; + } + + desc->t = t; + insert_timer_desc(desc); + + return; + +close_pipe: + close(desc->pipe[0]); + close(desc->pipe[1]); +del_timer: + timer_delete(desc->timerid); +free_timer_desc: + free(desc); +} + +static void sigalrm_handler(int signum) +{ + struct timer_desc *t; + uint64_t val = 0; + + assert(signum == SIGALRM); + assert(!list_empty(&timer_list)); + + t = list_first_entry(&timer_list, struct timer_desc, list); + write(t->pipe[1], &val, sizeof(val)); +} + +void init_timer(void) +{ + if (install_sighandler(SIGALRM, sigalrm_handler, false) < 0) + panic("install_sighandler() failed: %m"); } struct event_info { diff --git a/sheep/Makefile.am b/sheep/Makefile.am index 32bc1c0..84b2766 100644 --- a/sheep/Makefile.am +++ b/sheep/Makefile.am @@ -43,7 +43,7 @@ if BUILD_TRACE sheep_SOURCES += trace/trace.c trace/mcount.S trace/stabs.c trace/graph.c endif -sheep_LDADD = ../lib/libsheepdog.a -lpthread -lm\ +sheep_LDADD = ../lib/libsheepdog.a -lpthread -lm -lrt\ $(libcpg_LIBS) $(libcfg_LIBS) $(libacrd_LIBS) $(LIBS) sheep_DEPENDENCIES = ../lib/libsheepdog.a diff --git a/sheep/cluster/local.c b/sheep/cluster/local.c index 142221f..ffcc9b5 100644 --- a/sheep/cluster/local.c +++ b/sheep/cluster/local.c @@ -28,7 +28,6 @@ static const char *shmfile = "/tmp/sheepdog_shm"; static int shmfd; -static int sigfd; static int block_event_pos; static int nonblock_event_pos; static struct local_node this_node; @@ -503,7 +502,7 @@ static void local_handler(int listen_fd, int events, void *data) sd_dprintf("read siginfo"); - ret = read(sigfd, &siginfo, sizeof(siginfo)); + ret = read(listen_fd, &siginfo, sizeof(siginfo)); assert(ret == sizeof(siginfo)); shm_queue_lock(); @@ -523,9 +522,23 @@ static int local_get_local_addr(uint8_t *myaddr) return 0; } +static int sigusr1_pipe[2]; + +static void sigusr1_handler(int signum) +{ + int ret; + struct signalfd_siginfo siginfo; + + assert(signum == SIGUSR1); + + siginfo.ssi_signo = SIGUSR1; + ret = write(sigusr1_pipe[1], &siginfo, sizeof(siginfo)); + if (ret != sizeof(siginfo)) + panic("write: %m"); +} + static int local_init(const char *option) { - sigset_t mask; int ret; static struct timer t = { .callback = check_pids, @@ -537,19 +550,17 @@ static int local_init(const char *option) shm_queue_init(); - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - sigprocmask(SIG_BLOCK, &mask, NULL); + ret = install_sighandler(SIGUSR1, sigusr1_handler, false); + if (ret < 0) + panic("install_sighandler: %m"); - sigfd = signalfd(-1, &mask, SFD_NONBLOCK); - if (sigfd < 0) { - sd_eprintf("failed to create a signal fd: %m"); - return -1; - } + ret = pipe(sigusr1_pipe); + if (ret < 0) + panic("pipe: %m"); add_timer(&t, PROCESS_CHECK_INTERVAL); - ret = register_event(sigfd, local_handler, NULL); + ret = register_event(sigusr1_pipe[0], local_handler, NULL); if (ret) { sd_eprintf("failed to register local event handler (%d)", ret); return -1; diff --git a/sheep/sheep.c b/sheep/sheep.c index cda8493..9e6de4d 100644 --- a/sheep/sheep.c +++ b/sheep/sheep.c @@ -145,26 +145,39 @@ static void signal_handler(int listen_fd, int events, void *data) } } +static int sigterm_pipe[2]; + +static void sigterm_handler(int signum) +{ + int ret; + struct signalfd_siginfo siginfo; + + assert(signum == SIGTERM); + + memset(&siginfo, 0, sizeof(siginfo)); + siginfo.ssi_signo = SIGTERM; + ret = write(sigterm_pipe[1], &siginfo, sizeof(siginfo)); + if (ret != sizeof(siginfo)) + panic("handling SIGTERM failed: %m"); +} + static int init_signal(void) { - sigset_t mask; int ret; ret = trace_init_signal(); if (ret) return ret; - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigprocmask(SIG_BLOCK, &mask, NULL); + ret = install_sighandler(SIGTERM, sigterm_handler, true); + if (ret < 0) + panic("install_sighandler: %m"); - sigfd = signalfd(-1, &mask, SFD_NONBLOCK); - if (sigfd < 0) { - sd_eprintf("failed to create a signal fd: %m"); - return -1; - } + ret = pipe(sigterm_pipe); + if (ret < 0) + panic("pipe: %m"); - ret = register_event(sigfd, signal_handler, NULL); + ret = register_event(sigterm_pipe[0], signal_handler, NULL); if (ret) { sd_eprintf("failed to register signal handler (%d)", ret); return -1; @@ -556,6 +569,8 @@ int main(int argc, char **argv) sheep_info.port = port; early_log_init(log_format, &sheep_info); + init_timer(); + if (nr_vnodes == 0) { sys->gateway_only = true; sys->disk_space = 0; diff --git a/shepherd/Makefile.am b/shepherd/Makefile.am index f7fd998..001ef28 100644 --- a/shepherd/Makefile.am +++ b/shepherd/Makefile.am @@ -25,7 +25,7 @@ sbin_PROGRAMS = shepherd shepherd_SOURCES = shepherd.c -shepherd_LDADD = ../lib/libsheepdog.a +shepherd_LDADD = ../lib/libsheepdog.a -lrt shepherd_DEPENDENCIES = ../lib/libsheepdog.a EXTRA_DIST = -- 1.7.2.5 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
