From d6572f074a899e692a8233256d48901c1ee5a8aa Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Tue, 1 May 2012 10:20:42 +0400 Subject: [PATCH] A fix for https://bugs.launchpad.net/tarantool/+bug/992171 A fix for https://bugs.launchpad.net/tarantool/+bug/992171 "SAVE SNAPSHOT process (dumper) does not respond to signals" Reset the signal mask/handler after a fork to their defaults. Make sure that when the snapshot dumper process is terminated with a signal, we report it back to the user. No test case since it would be hard to do a concurrent test in our framework yet. --- include/tarantool_pthread.h | 5 +++++ src/log_io.m | 2 +- src/tarantool.m | 30 +++++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/tarantool_pthread.h b/include/tarantool_pthread.h index e1f781dd52..41094a031a 100644 --- a/include/tarantool_pthread.h +++ b/include/tarantool_pthread.h @@ -149,5 +149,10 @@ tt_pthread_error(e); \ }) +#define tt_pthread_atfork(prepare, parent, child)\ +({ int e = pthread_atfork(prepare, parent, child);\ + tt_pthread_error(e); \ +}) + #endif /* TARANTOOL_PTHREAD_H_INCLUDED */ diff --git a/src/log_io.m b/src/log_io.m index ac1ef27c48..684842164a 100644 --- a/src/log_io.m +++ b/src/log_io.m @@ -1254,7 +1254,7 @@ wal_writer_child() static void wal_writer_init_once() { - pthread_atfork(NULL, NULL, wal_writer_child); + tt_pthread_atfork(NULL, NULL, wal_writer_child); } /** diff --git a/src/tarantool.m b/src/tarantool.m index 8df1136927..b9a397193e 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -57,6 +57,7 @@ #include <util.h> #include <third_party/gopt/gopt.h> #include <cfg/warning.h> +#include "tarantool_pthread.h" static pid_t master_pid; @@ -277,7 +278,8 @@ snapshot(void *ev, int events __attribute__((unused))) */ wait_for_child(p); assert(p == fiber->cw.rpid); - return WEXITSTATUS(fiber->cw.rstatus); + return (WIFSIGNALED(fiber->cw.rstatus) ? EINTR : + WEXITSTATUS(fiber->cw.rstatus)); } fiber_set_name(fiber, "dumper"); @@ -312,6 +314,31 @@ signal_free(void) ev_signal_stop(&sigs[i]); } +/** Make sure the child has a default signal disposition. */ +static void +signal_reset() +{ + struct sigaction sa; + + /* Reset all signals to their defaults. */ + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + + if (sigaction(SIGUSR1, &sa, NULL) == -1 || + sigaction(SIGINT, &sa, NULL) == -1 || + sigaction(SIGTERM, &sa, NULL) == -1 || + sigaction(SIGHUP, &sa, NULL) == -1) + say_syserror("sigaction"); + + /* Unblock any signals blocked by libev. */ + sigset_t sigset; + sigfillset(&sigset); + if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) == -1) + say_syserror("sigprocmask"); +} + + /** * Adjust the process signal mask and add handlers for signals. */ @@ -341,6 +368,7 @@ signal_init(void) ev_signal_start(&sigs[3]); atexit(signal_free); + tt_pthread_atfork(NULL, NULL, signal_reset); } static void -- GitLab