From 9606d987722ee5b89bbfae230389d3385a3884b0 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 14 May 2020 17:49:44 +0200 Subject: Replace standard signal handling in initd with signalfd + epoll Signed-off-by: David Oberhollenzer --- initd/init.h | 2 ++ initd/main.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++------------ initd/runsvc.c | 17 +++++---------- 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/initd/init.h b/initd/init.h index 5618ccd..5ac6d22 100644 --- a/initd/init.h +++ b/initd/init.h @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include #include #include diff --git a/initd/main.c b/initd/main.c index d92a823..9c4bf78 100644 --- a/initd/main.c +++ b/initd/main.c @@ -58,13 +58,17 @@ static void start_service(svc_run_data_t *rt) print_status(rt); } -static void handle_signal(int signo) +static void handle_signal(int fd) { + struct signalfd_siginfo info; svc_run_data_t *rt; int status; pid_t pid; - switch (signo) { + if (read(fd, &info, sizeof(info)) < (ssize_t)sizeof(info)) + return; + + switch (info.ssi_signo) { case SIGTERM: config_set_target(TGT_SHUTDOWN); break; @@ -96,20 +100,43 @@ static void handle_signal(int signo) int main(void) { + struct epoll_event ev; svc_run_data_t *rt; - struct sigaction act; + int ret, sfd, epfd; + sigset_t sigmask; + + cli(NULL); if (config_load()) return EXIT_FAILURE; - memset(&act, 0, sizeof(act)); - act.sa_handler = handle_signal; + epfd = epoll_create1(EPOLL_CLOEXEC); + if (epfd < 0) { + perror("epoll_create"); + return EXIT_FAILURE; + } - sigaction(SIGTERM, &act, NULL); - sigaction(SIGINT, &act, NULL); - sigaction(SIGHUP, &act, NULL); - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGCHLD, &act, NULL); + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGTERM); + sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGUSR1); + sigaddset(&sigmask, SIGCHLD); + + sfd = signalfd(-1, &sigmask, SFD_CLOEXEC); + if (sfd < 0) { + perror("signalfd"); + return EXIT_FAILURE; + } + + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN; + ev.data.fd = sfd; + + if (epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &ev)) { + perror("adding signalfd to epoll"); + return EXIT_FAILURE; + } if (reboot(LINUX_REBOOT_CMD_CAD_OFF)) perror("cannot disable CTRL+ALT+DEL"); @@ -117,10 +144,22 @@ int main(void) for (;;) { rt = config_dequeue(); - if (rt == NULL) { - pause(); - } else { + if (rt != NULL) { start_service(rt); + continue; + } + + ret = epoll_wait(epfd, &ev, 1, -1); + if (ret == 0) + continue; + + if (ret < 0) { + perror("epoll wait"); + return EXIT_FAILURE; + } + + if (ev.data.fd == sfd) { + handle_signal(sfd); } } diff --git a/initd/runsvc.c b/initd/runsvc.c index 5495f15..682f4c6 100644 --- a/initd/runsvc.c +++ b/initd/runsvc.c @@ -195,18 +195,6 @@ pid_t runsvc(service_t *svc) perror("fork"); if (pid == 0) { - cli(NULL); - - memset(&act, 0, sizeof(act)); - act.sa_handler = runsvc_sighandler; - sigaction(SIGTERM, &act, NULL); - sigaction(SIGINT, &act, NULL); - sigaction(SIGHUP, &act, NULL); - - act.sa_handler = SIG_DFL; - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGCHLD, &act, NULL); - if (setup_env()) exit(EXIT_FAILURE); @@ -218,6 +206,11 @@ pid_t runsvc(service_t *svc) exit(EXIT_FAILURE); } + memset(&act, 0, sizeof(act)); + act.sa_handler = runsvc_sighandler; + sigaction(SIGTERM, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGHUP, &act, NULL); sti(NULL); if (svc->flags & SVC_FLAG_SUB_REAPER) { -- cgit v1.2.3