]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: block SIGPIPE everywhere we can
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 3 Mar 2011 15:08:09 +0000 (07:08 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 3 Mar 2011 15:50:35 +0000 (07:50 -0800)
It's much better to get EPIPE than SIGPIPE.

Block SIGPIPE in all threads we create. In the daemon, block SIGPIPE in
the main thread.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/common/Thread.h
src/common/common_init.cc
src/common/signal.cc
src/common/signal.h

index a3f45e2500fbcdad52ffcf5a7d9eefab077ea3fe..5ab4bfd3c5f17767c20b5d19e599d072f2df7d37 100644 (file)
@@ -66,19 +66,21 @@ class Thread {
     }
 
     int r;
+
+    // The child thread will inherit our signal mask.  Set our signal mask to
+    // the set of signals we want to block.  (It's ok to block signals more
+    // signals than usual for a little while-- they will just be delivered to
+    // another thread or delieverd to this thread later.)
+    sigset_t old_sigset;
     if (g_code_env == CODE_ENVIRONMENT_LIBRARY) {
-      // The child thread will inherit our signal mask.  We want it to block all
-      // signals, so set our mask to that.  (It's ok to block signals for a
-      // little while-- they will just be delivered to another thread or
-      // delieverd to this thread later.)
-      sigset_t old_sigset;
-      block_all_signals(&old_sigset);
-      r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
-      restore_sigset(&old_sigset);
+      block_signals(&old_sigset, NULL);
     }
     else {
-      r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
+      int to_block[] = { SIGPIPE , 0 };
+      block_signals(&old_sigset, to_block);
     }
+    r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
+    restore_sigset(&old_sigset);
 
     if (thread_attr) 
       free(thread_attr);
index 09c948978ef2f1f3fc6ce83f6ff5fead7d6a89fd..fd29d4ec0c3aee52d0c232e2a7d15f74daaa1246 100644 (file)
@@ -134,6 +134,10 @@ void common_init(std::vector<const char*>& args, const char *module_type, int fl
     g_conf.log_to_stderr = LOG_TO_STDERR_SOME;
     set_cv(&g_conf.log_dir, "/var/log/ceph");
     set_cv(&g_conf.pid_file, "/var/run/ceph/$type.$id.pid");
+
+    // block SIGPIPE
+    int siglist[] = { SIGPIPE, 0 };
+    block_signals(NULL, siglist);
   }
   else {
     g_conf.pid_file = 0;
index e569cff19e78963cb2e0d860b0ceecce64e8531a..64886e149b63623b729f6dea44bb483163b59123 100644 (file)
@@ -124,10 +124,20 @@ void install_standard_sighandlers(void)
   install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
 }
 
-void block_all_signals(sigset_t *old_sigset)
+void block_signals(sigset_t *old_sigset, int *siglist)
 {
   sigset_t sigset;
-  sigfillset(&sigset);
+  if (!siglist) {
+    sigfillset(&sigset);
+  }
+  else {
+    int i = 0;
+    sigemptyset(&sigset);
+    while (siglist[i]) {
+      sigaddset(&sigset, siglist[i]);
+      ++i;
+    }
+  }
   sigdelset(&sigset, SIGKILL);
   if (pthread_sigmask(SIG_BLOCK, &sigset, old_sigset)) {
     derr << "block_all_signals: sigprocmask failed" << dendl;
index 1081e337cab19405999a1d26d489e9d5c14c53e3..ed9ef2891dcf9bef4072fc649b9b5622b6c6d0db 100644 (file)
@@ -32,10 +32,13 @@ void install_standard_sighandlers(void);
 // Other threads may have a different set (this is per-thread thing).
 std::string signal_mask_to_str();
 
-// Block all signals. On success, stores the old set of blocked signals in
+// Block a list of signals. If siglist == NULL, blocks all signals.
+// If not, the list is terminated with a 0 element.
+//
+// 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_all_signals(sigset_t *old_sigset);
+void block_signals(sigset_t *old_sigset, int *siglist);
 
 // Restore the set of blocked signals. Will not restore an invalid set of
 // blocked signals.