From: songbaisen Date: Mon, 9 May 2016 06:17:48 +0000 (+0800) Subject: global: log which process/command sent a signal X-Git-Tag: ses5-milestone5~439^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e7c4246d375c58a7454b3753716ea310bf525547;p=ceph.git global: log which process/command sent a signal Signed-off-by:song baisen --- diff --git a/src/global/signal_handler.cc b/src/global/signal_handler.cc index 86e90e9ebcab..ad11434cffe8 100644 --- a/src/global/signal_handler.cc +++ b/src/global/signal_handler.cc @@ -23,7 +23,7 @@ #include #include #include - +#include "common/errno.h" #if defined(_AIX) extern char *sys_siglist[]; #endif @@ -150,6 +150,32 @@ void install_standard_sighandlers(void) #include "common/Thread.h" #include +void get_name_by_pid(pid_t pid, char *task_name) +{ + char proc_pid_path[PATH_MAX] = {0}; + snprintf(proc_pid_path, PATH_MAX, "/proc/%d/cmdline", pid); + int fd = open(proc_pid_path, O_RDONLY); + + if (fd < 0) { + fd = -errno; + derr << "Fail to open '" << proc_pid_path + << "' error = " << cpp_strerror(fd) + << dendl; + return; + } + + int ret = read(fd, task_name, PATH_MAX-1); + if (ret < 0) { + ret = -errno; + derr << "Fail to read '" << proc_pid_path + << "' error = " << cpp_strerror(ret) + << dendl; + } + + close(fd); +} + + /** * safe async signal handler / dispatcher * @@ -172,6 +198,14 @@ struct SignalHandler : public Thread { /// for an individual signal struct safe_handler { + + safe_handler() { + memset(pipefd, 0, sizeof(pipefd)); + memset(&handler, 0, sizeof(handler)); + memset(&info_t, 0, sizeof(info_t)); + } + + siginfo_t info_t; int pipefd[2]; // write to [1], read from [0] signal_handler_t handler; }; @@ -247,14 +281,20 @@ struct SignalHandler : public Thread { if (handlers[signum]) { r = read(handlers[signum]->pipefd[0], &v, 1); if (r == 1) { + char task_name[PATH_MAX] = "unknown"; + siginfo_t * siginfo = &handlers[signum]->info_t; + get_name_by_pid(siginfo->si_pid, task_name); + derr << "received signal: " << sys_siglist[signum] + << " from " << " PID: " << siginfo->si_pid + << " task name: " << task_name + << " UID: " << siginfo->si_uid + << dendl; handlers[signum]->handler(signum); } } } lock.Unlock(); - } else { - //cout << "no data, got r=" << r << " errno=" << errno << std::endl; - } + } } return NULL; } @@ -269,15 +309,25 @@ struct SignalHandler : public Thread { assert(r == 1); } + void queue_signal_info(int signum, siginfo_t *siginfo, void * content) { + // If this signal handler is registered, the callback must be + // defined. We can do this without the lock because we will never + // have the signal handler defined without the handlers entry also + // being filled in. + assert(handlers[signum]); + memcpy(&handlers[signum]->info_t, siginfo, sizeof(siginfo_t)); + int r = write(handlers[signum]->pipefd[1], " ", 1); + assert(r == 1); + } + void register_handler(int signum, signal_handler_t handler, bool oneshot); void unregister_handler(int signum, signal_handler_t handler); }; static SignalHandler *g_signal_handler = NULL; -static void handler_hook(int signum) -{ - g_signal_handler->queue_signal(signum); +static void handler_signal_hook(int signum, siginfo_t * siginfo, void * content) { + g_signal_handler->queue_signal_info(signum, siginfo, content); } void SignalHandler::register_handler(int signum, signal_handler_t handler, bool oneshot) @@ -306,10 +356,9 @@ void SignalHandler::register_handler(int signum, signal_handler_t handler, bool struct sigaction act; memset(&act, 0, sizeof(act)); - act.sa_handler = handler_hook; + act.sa_handler = (signal_handler_t)handler_signal_hook; sigfillset(&act.sa_mask); // mask all signals in the handler - act.sa_flags = oneshot ? SA_RESETHAND : 0; - + act.sa_flags = SA_SIGINFO | (oneshot ? SA_RESETHAND : 0); int ret = sigaction(signum, &act, &oldact); assert(ret == 0); }