]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
global: log which process/command sent a signal 8964/head
authorsongbaisen <song.baisen@zte.com.cn>
Mon, 9 May 2016 06:17:48 +0000 (14:17 +0800)
committersongbaisen <song.baisen@zte.com.cn>
Fri, 3 Jun 2016 06:02:57 +0000 (14:02 +0800)
Signed-off-by:song baisen <song.baisen@zte.com.cn>

src/global/signal_handler.cc

index 86e90e9ebcabe7965672212212752766ad1c044d..ad11434cffe867f4960f63e1f1ab482871170f75 100644 (file)
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-
+#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 <errno.h>
 
+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);
 }