diff --git a/src/Makefile.am b/src/Makefile.am index 6b12a38e513..ac67ac6790d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -649,6 +649,7 @@ libcommon_files = \ common/buffer.cc \ common/code_environment.cc \ common/signal.cc \ + global/signal_handler.cc \ common/simple_spin.cc \ common/Thread.cc \ include/ceph_fs.cc \ @@ -665,7 +666,7 @@ libcommon_files = \ common/hex.cc \ common/entity_name.cc \ common/ceph_crypto.cc \ - common/pidfile.cc \ + global/pidfile.cc \ include/addr_parsing.c \ $(crush_files) @@ -820,6 +821,7 @@ noinst_HEADERS = \ common/common_init.h\ common/code_environment.h \ common/signal.h\ + global/signal_handler.h\ common/simple_spin.h\ common/dyn_snprintf.h\ common/run_cmd.h\ @@ -1117,7 +1119,7 @@ noinst_HEADERS = \ tools/gui.h\ tools/gui_resources.h\ test/osd/RadosModel.h\ - common/pidfile.h\ + global/pidfile.h\ common/sync_filesystem.h all_sources = $(cmon_SOURCES) $(ceph_SOURCES) $(cephfs_SOURCES) $(librados_config_SOURCES) $(cauthtool_SOURCES) $(monmaptool_SOURCES) \ diff --git a/src/common/common_init.cc b/src/common/common_init.cc index 551fd9f0c2e..3884d9d632b 100644 --- a/src/common/common_init.cc +++ b/src/common/common_init.cc @@ -20,7 +20,6 @@ #include "common/config.h" #include "common/errno.h" #include "common/safe_io.h" -#include "common/signal.h" #include "common/version.h" #include "include/color.h" diff --git a/src/common/signal.cc b/src/common/signal.cc index 0e659acf0f6..183c52fab73 100644 --- a/src/common/signal.cc +++ b/src/common/signal.cc @@ -15,7 +15,7 @@ #include "common/BackTrace.h" #include "common/DoutStreambuf.h" #include "common/ProfLogger.h" -#include "common/pidfile.h" +#include "global/pidfile.h" #include "common/debug.h" #include "common/signal.h" #include "common/config.h" @@ -26,86 +26,6 @@ #include <sys/stat.h> #include <sys/types.h> -void install_sighandler(int signum, signal_handler_t handler, int flags) -{ - int ret; - struct sigaction oldact; - struct sigaction act; - memset(&act, 0, sizeof(act)); - - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = flags; - - ret = sigaction(signum, &act, &oldact); - if (ret != 0) { - char buf[1024]; - snprintf(buf, sizeof(buf), "install_sighandler: sigaction returned " - "%d when trying to install a signal handler for %s\n", - ret, sys_siglist[signum]); - dout_emergency(buf); - exit(1); - } -} - -void sighup_handler(int signum) -{ - g_ceph_context.reopen_logs(); -} - -static void reraise_fatal(int signum) -{ - // Use default handler to dump core - int ret = raise(signum); - - // Normally, we won't get here. If we do, something is very weird. - char buf[1024]; - if (ret) { - snprintf(buf, sizeof(buf), "reraise_fatal: failed to re-raise " - "signal %d\n", signum); - dout_emergency(buf); - } - else { - snprintf(buf, sizeof(buf), "reraise_fatal: default handler for " - "signal %d didn't terminate the process?\n", signum); - dout_emergency(buf); - } - exit(1); -} - -static void handle_shutdown_signal(int signum) -{ - char buf[1024]; - snprintf(buf, sizeof(buf), "*** Caught signal (%s) **\n " - "in thread %p. Shutting down.\n", - sys_siglist[signum], (void*)pthread_self()); - dout_emergency(buf); - pidfile_remove(); - reraise_fatal(signum); -} - -static void handle_fatal_signal(int signum) -{ - // This code may itself trigger a SIGSEGV if the heap is corrupt. In that - // case, SA_RESETHAND specifies that the default signal handler-- - // presumably dump core-- will handle it. - char buf[1024]; - snprintf(buf, sizeof(buf), "*** Caught signal (%s) **\n " - "in thread %p\n", sys_siglist[signum], (void*)pthread_self()); - dout_emergency(buf); - pidfile_remove(); - - // TODO: don't use an ostringstream here. It could call malloc(), which we - // don't want inside a signal handler. - // Also fix the backtrace code not to allocate memory. - BackTrace bt(0); - ostringstream oss; - bt.print(oss); - dout_emergency(oss.str()); - - reraise_fatal(signum); -} - std::string signal_mask_to_str() { sigset_t old_sigset; @@ -126,21 +46,6 @@ std::string signal_mask_to_str() return oss.str(); } -void install_standard_sighandlers(void) -{ - install_sighandler(SIGHUP, sighup_handler, SA_RESTART); - install_sighandler(SIGSEGV, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGABRT, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGBUS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGILL, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGFPE, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGXCPU, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGXFSZ, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGTERM, handle_shutdown_signal, SA_RESETHAND | SA_NODEFER); - install_sighandler(SIGINT, handle_shutdown_signal, SA_RESETHAND | SA_NODEFER); -} - /* Block the signals in 'siglist'. If siglist == NULL, block all signals. */ void block_signals(const int *siglist, sigset_t *old_sigset) { diff --git a/src/common/signal.h b/src/common/signal.h index cac3c7bb656..4b323de4735 100644 --- a/src/common/signal.h +++ b/src/common/signal.h @@ -18,19 +18,9 @@ #include <signal.h> #include <string> -typedef void (*signal_handler_t)(int); - -void install_sighandler(int signum, signal_handler_t handler, int flags); - -// handles SIGHUP -void sighup_handler(int signum); - -// Install the standard Ceph signal handlers -void install_standard_sighandlers(void); - // Returns a string showing the set of blocked signals for the calling thread. // Other threads may have a different set (this is per-thread thing). -std::string signal_mask_to_str(); +extern std::string signal_mask_to_str(); // Block a list of signals. If siglist == NULL, blocks all signals. // If not, the list is terminated with a 0 element. @@ -38,15 +28,15 @@ std::string signal_mask_to_str(); // On success, stores the old set of blocked signals in // old_sigset. On failure, stores an invalid set of blocked signals in // old_sigset. -void block_signals(const int *siglist, sigset_t *old_sigset); +extern void block_signals(const int *siglist, sigset_t *old_sigset); // Restore the set of blocked signals. Will not restore an invalid set of // blocked signals. -void restore_sigset(const sigset_t *old_sigset); +extern void restore_sigset(const sigset_t *old_sigset); // Unblock all signals. On success, stores the old set of blocked signals in // old_sigset. On failure, stores an invalid set of blocked signals in // old_sigset. -void unblock_all_signals(sigset_t *old_sigset); +extern void unblock_all_signals(sigset_t *old_sigset); #endif diff --git a/src/global/global_init.cc b/src/global/global_init.cc index f1f4693e907..f83a27588b9 100644 --- a/src/global/global_init.cc +++ b/src/global/global_init.cc @@ -19,10 +19,11 @@ #include "common/common_init.h" #include "common/config.h" #include "common/errno.h" -#include "common/pidfile.h" #include "common/safe_io.h" #include "common/signal.h" #include "common/version.h" +#include "global/pidfile.h" +#include "global/signal_handler.h" #include "include/color.h" #include <errno.h> diff --git a/src/common/pidfile.cc b/src/global/pidfile.cc similarity index 97% rename from src/common/pidfile.cc rename to src/global/pidfile.cc index a432489eae7..23e825fdd59 100644 --- a/src/common/pidfile.cc +++ b/src/global/pidfile.cc @@ -12,10 +12,10 @@ * */ +#include "common/debug.h" #include "common/errno.h" -#include "common/pidfile.h" #include "common/safe_io.h" -#include "debug.h" +#include "global/pidfile.h" #include <errno.h> #include <fcntl.h> diff --git a/src/common/pidfile.h b/src/global/pidfile.h similarity index 100% rename from src/common/pidfile.h rename to src/global/pidfile.h diff --git a/src/global/signal_handler.cc b/src/global/signal_handler.cc new file mode 100644 index 00000000000..a723744edb5 --- /dev/null +++ b/src/global/signal_handler.cc @@ -0,0 +1,122 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "common/BackTrace.h" +#include "common/DoutStreambuf.h" +#include "common/ProfLogger.h" +#include "common/config.h" +#include "common/debug.h" +#include "global/pidfile.h" +#include "global/signal_handler.h" + +#include <signal.h> +#include <sstream> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> + +void install_sighandler(int signum, signal_handler_t handler, int flags) +{ + int ret; + struct sigaction oldact; + struct sigaction act; + memset(&act, 0, sizeof(act)); + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = flags; + + ret = sigaction(signum, &act, &oldact); + if (ret != 0) { + char buf[1024]; + snprintf(buf, sizeof(buf), "install_sighandler: sigaction returned " + "%d when trying to install a signal handler for %s\n", + ret, sys_siglist[signum]); + dout_emergency(buf); + exit(1); + } +} + +void sighup_handler(int signum) +{ + g_ceph_context.reopen_logs(); +} + +static void reraise_fatal(int signum) +{ + // Use default handler to dump core + int ret = raise(signum); + + // Normally, we won't get here. If we do, something is very weird. + char buf[1024]; + if (ret) { + snprintf(buf, sizeof(buf), "reraise_fatal: failed to re-raise " + "signal %d\n", signum); + dout_emergency(buf); + } + else { + snprintf(buf, sizeof(buf), "reraise_fatal: default handler for " + "signal %d didn't terminate the process?\n", signum); + dout_emergency(buf); + } + exit(1); +} + +static void handle_shutdown_signal(int signum) +{ + char buf[1024]; + snprintf(buf, sizeof(buf), "*** Caught signal (%s) **\n " + "in thread %p. Shutting down.\n", + sys_siglist[signum], (void*)pthread_self()); + dout_emergency(buf); + pidfile_remove(); + reraise_fatal(signum); +} + +static void handle_fatal_signal(int signum) +{ + // This code may itself trigger a SIGSEGV if the heap is corrupt. In that + // case, SA_RESETHAND specifies that the default signal handler-- + // presumably dump core-- will handle it. + char buf[1024]; + snprintf(buf, sizeof(buf), "*** Caught signal (%s) **\n " + "in thread %p\n", sys_siglist[signum], (void*)pthread_self()); + dout_emergency(buf); + pidfile_remove(); + + // TODO: don't use an ostringstream here. It could call malloc(), which we + // don't want inside a signal handler. + // Also fix the backtrace code not to allocate memory. + BackTrace bt(0); + ostringstream oss; + bt.print(oss); + dout_emergency(oss.str()); + + reraise_fatal(signum); +} + +void install_standard_sighandlers(void) +{ + install_sighandler(SIGHUP, sighup_handler, SA_RESTART); + install_sighandler(SIGSEGV, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGABRT, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGBUS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGILL, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGFPE, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGXCPU, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGXFSZ, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGTERM, handle_shutdown_signal, SA_RESETHAND | SA_NODEFER); + install_sighandler(SIGINT, handle_shutdown_signal, SA_RESETHAND | SA_NODEFER); +} diff --git a/src/global/signal_handler.h b/src/global/signal_handler.h new file mode 100644 index 00000000000..1494f32abcb --- /dev/null +++ b/src/global/signal_handler.h @@ -0,0 +1,31 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_GLOBAL_SIGNAL_HANDLER_H +#define CEPH_GLOBAL_SIGNAL_HANDLER_H + +#include <signal.h> +#include <string> + +typedef void (*signal_handler_t)(int); + +void install_sighandler(int signum, signal_handler_t handler, int flags); + +// handles SIGHUP +void sighup_handler(int signum); + +// Install the standard Ceph signal handlers +void install_standard_sighandlers(void); + +#endif diff --git a/src/test/signals.cc b/src/test/signals.cc index 344cc59a787..248325420a7 100644 --- a/src/test/signals.cc +++ b/src/test/signals.cc @@ -1,5 +1,6 @@ #include "common/config.h" #include "common/signal.h" +#include "global/signal_handler.h" #include "gtest/gtest.h"