]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Revert "SIGPIPE suppression for platforms without SO_NOSIGPIPE or MSG_NOSIGNAL"
authorGreg Farnum <gfarnum@redhat.com>
Tue, 3 Oct 2017 22:06:25 +0000 (15:06 -0700)
committerGreg Farnum <gfarnum@redhat.com>
Wed, 4 Oct 2017 14:10:23 +0000 (07:10 -0700)
This reverts commit 131deb39769c1187c334ee84f552d3be01f1751b. It added
code that shouldn't have entered the project repo.

Conflicts:
src/msg/async/AsyncConnection.cc
src/msg/async/AsyncConnection.h
src/msg/simple/Pipe.cc
src/msg/simple/Pipe.h

Signed-off-by: Greg Farnum <gfarnum@redhat.com>
COPYING
src/include/sock_compat.h
src/msg/async/AsyncConnection.h
src/msg/async/PosixStack.cc
src/msg/async/net_handler.cc
src/msg/simple/Pipe.cc
src/msg/simple/Pipe.h

diff --git a/COPYING b/COPYING
index b7371e4f9c0592b9cf9161bd6b6bfaf648ce75fc..a87427936a5eca14d7895aca5afa099fc1242061 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -145,8 +145,3 @@ Files: src/include/timegm.h
   Copyright (C) Copyright Howard Hinnant
   Copyright (C) Copyright 2010-2011 Vicente J. Botet Escriba
   License: Boost Software License, Version 1.0
-
-Files: src/msg/async/AsyncConnection.cc, src/msg/simple/Pipe.cc (sigpipe suppression)
-  Copyright (C) 2010 Tomash Brechko.  All rights reserved.
-  License: GPL3
-
index 56eb92bd6e3c20de3f4fa65895a0c7f6c2d5bee9..5faacc343edc67a7c8ae774f0e50cab46984080c 100644 (file)
 # define MSG_MORE 0
 #endif
 
+/*
+ * On BSD SO_NOSIGPIPE can be set via setsockopt to block SIGPIPE.
+ */
+#ifndef MSG_NOSIGNAL
+# define MSG_NOSIGNAL 0
+# ifdef SO_NOSIGPIPE
+#  define CEPH_USE_SO_NOSIGPIPE
+# else
+#  error "Cannot block SIGPIPE!"
+# endif
+#endif
+
 #endif
index 005b7c13ab29af3f1d618075c362902fa0d3fdf9..ab2ff2c4ab05054a8a2b579d0eed26c33a97f9ad 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <atomic>
 #include <pthread.h>
-#include <signal.h>
 #include <climits>
 #include <list>
 #include <mutex>
index 655b3c59ca0ff9d1ad1f4d40587ff6c68047a8f8..c91acb9b195e50cf1c5d3692daa8ee7e62ef31f1 100644 (file)
@@ -40,11 +40,6 @@ class PosixConnectedSocketImpl final : public ConnectedSocketImpl {
   int _fd;
   entity_addr_t sa;
   bool connected;
-#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-  sigset_t sigpipe_mask;
-  bool sigpipe_pending;
-  bool sigpipe_unblock;
-#endif
 
  public:
   explicit PosixConnectedSocketImpl(NetHandler &h, const entity_addr_t &sa, int f, bool connected)
@@ -76,83 +71,14 @@ class PosixConnectedSocketImpl final : public ConnectedSocketImpl {
     return r;
   }
 
-  /*
-   SIGPIPE suppression - for platforms without SO_NOSIGPIPE or MSG_NOSIGNAL
-    http://krokisplace.blogspot.in/2010/02/suppressing-sigpipe-in-library.html 
-    http://www.microhowto.info/howto/ignore_sigpipe_without_affecting_other_threads_in_a_process.html 
-  */
-  static void suppress_sigpipe()
-  {
-  #if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-    /*
-      We want to ignore possible SIGPIPE that we can generate on write.
-      SIGPIPE is delivered *synchronously* and *only* to the thread
-      doing the write.  So if it is reported as already pending (which
-      means the thread blocks it), then we do nothing: if we generate
-      SIGPIPE, it will be merged with the pending one (there's no
-      queuing), and that suits us well.  If it is not pending, we block
-      it in this thread (and we avoid changing signal action, because it
-      is per-process).
-    */
-    sigset_t pending;
-    sigemptyset(&pending);
-    sigpending(&pending);
-    sigpipe_pending = sigismember(&pending, SIGPIPE);
-    if (!sigpipe_pending) {
-      sigset_t blocked;
-      sigemptyset(&blocked);
-      pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &blocked);
-
-      /* Maybe is was blocked already?  */
-      sigpipe_unblock = ! sigismember(&blocked, SIGPIPE);
-    }
-  #endif /* !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) */
-  }
-
-  static void restore_sigpipe()
-  {
-  #if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-    /*
-      If SIGPIPE was pending already we do nothing.  Otherwise, if it
-      become pending (i.e., we generated it), then we sigwait() it (thus
-      clearing pending status).  Then we unblock SIGPIPE, but only if it
-      were us who blocked it.
-    */
-    if (!sigpipe_pending) {
-      sigset_t pending;
-      sigemptyset(&pending);
-      sigpending(&pending);
-      if (sigismember(&pending, SIGPIPE)) {
-        /*
-          Protect ourselves from a situation when SIGPIPE was sent
-          by the user to the whole process, and was delivered to
-          other thread before we had a chance to wait for it.
-        */
-        static const struct timespec nowait = { 0, 0 };
-        TEMP_FAILURE_RETRY(sigtimedwait(&sigpipe_mask, NULL, &nowait));
-      }
-
-      if (sigpipe_unblock)
-        pthread_sigmask(SIG_UNBLOCK, &sigpipe_mask, NULL);
-    }
-  #endif  /* !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) */
-  }
-
   // return the sent length
   // < 0 means error occured
   static ssize_t do_sendmsg(int fd, struct msghdr &msg, unsigned len, bool more)
   {
-    suppress_sigpipe();
-
     size_t sent = 0;
     while (1) {
       ssize_t r;
-  #if defined(MSG_NOSIGNAL)
       r = ::sendmsg(fd, &msg, MSG_NOSIGNAL | (more ? MSG_MORE : 0));
-  #else
-      r = ::sendmsg(fd, &msg, (more ? MSG_MORE : 0));
-  #endif /* defined(MSG_NOSIGNAL) */
-
       if (r < 0) {
         if (errno == EINTR) {
           continue;
@@ -178,7 +104,6 @@ class PosixConnectedSocketImpl final : public ConnectedSocketImpl {
         }
       }
     }
-    restore_sigpipe();
     return (ssize_t)sent;
   }
 
index 19adb2c83f2065ec5d0e19edaae7410756f99606..99ca1f32d9279462fe6b98ca36d484a3ca15b31d 100644 (file)
@@ -119,7 +119,7 @@ int NetHandler::set_socket_options(int sd, bool nodelay, int size)
   }
 
   // block ESIGPIPE
-#ifdef SO_NOSIGPIPE
+#ifdef CEPH_USE_SO_NOSIGPIPE
   int val = 1;
   r = ::setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val));
   if (r) {
index a03f005b02ba93567b586add1772dcbbf9bb7142..2f7115b447321efe4f7817259b30101b7b530e9a 100644 (file)
@@ -911,7 +911,7 @@ void Pipe::set_socket_options()
   }
 
   // block ESIGPIPE
-#if defined(SO_NOSIGPIPE)
+#ifdef CEPH_USE_SO_NOSIGPIPE
   int val = 1;
   int r = ::setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val));
   if (r) {
@@ -2261,91 +2261,20 @@ int Pipe::read_message(Message **pm, AuthSessionHandler* auth_handler)
   return ret;
 }
 
-/* 
- SIGPIPE suppression - for platforms without SO_NOSIGPIPE or MSG_NOSIGNAL
-  http://krokisplace.blogspot.in/2010/02/suppressing-sigpipe-in-library.html 
-  http://www.microhowto.info/howto/ignore_sigpipe_without_affecting_other_threads_in_a_process.html 
-*/
-void Pipe::suppress_sigpipe()
-{
-#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-  /*
-    We want to ignore possible SIGPIPE that we can generate on write.
-    SIGPIPE is delivered *synchronously* and *only* to the thread
-    doing the write.  So if it is reported as already pending (which
-    means the thread blocks it), then we do nothing: if we generate
-    SIGPIPE, it will be merged with the pending one (there's no
-    queuing), and that suits us well.  If it is not pending, we block
-    it in this thread (and we avoid changing signal action, because it
-    is per-process).
-  */
-  sigset_t pending;
-  sigemptyset(&pending);
-  sigpending(&pending);
-  sigpipe_pending = sigismember(&pending, SIGPIPE);
-  if (!sigpipe_pending) {
-    sigset_t blocked;
-    sigemptyset(&blocked);
-    pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &blocked);
-
-    /* Maybe is was blocked already?  */
-    sigpipe_unblock = ! sigismember(&blocked, SIGPIPE);
-  }
-#endif  /* !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) */
-}
-
-
-void Pipe::restore_sigpipe()
-{
-#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-  /*
-    If SIGPIPE was pending already we do nothing.  Otherwise, if it
-    become pending (i.e., we generated it), then we sigwait() it (thus
-    clearing pending status).  Then we unblock SIGPIPE, but only if it
-    were us who blocked it.
-  */
-  if (!sigpipe_pending) {
-    sigset_t pending;
-    sigemptyset(&pending);
-    sigpending(&pending);
-    if (sigismember(&pending, SIGPIPE)) {
-      /*
-        Protect ourselves from a situation when SIGPIPE was sent
-        by the user to the whole process, and was delivered to
-        other thread before we had a chance to wait for it.
-      */
-      static const struct timespec nowait = { 0, 0 };
-      TEMP_FAILURE_RETRY(sigtimedwait(&sigpipe_mask, NULL, &nowait));
-    }
-
-    if (sigpipe_unblock)
-      pthread_sigmask(SIG_UNBLOCK, &sigpipe_mask, NULL);
-  }
-#endif  /* !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE) */
-}
-
-
 int Pipe::do_sendmsg(struct msghdr *msg, unsigned len, bool more)
 {
-  suppress_sigpipe();
   while (len > 0) {
     int r;
-#if defined(MSG_NOSIGNAL)
     r = ::sendmsg(sd, msg, MSG_NOSIGNAL | (more ? MSG_MORE : 0));
-#else
-    r = ::sendmsg(sd, msg, (more ? MSG_MORE : 0));
-#endif
     if (r == 0) 
       ldout(msgr->cct,10) << "do_sendmsg hmm do_sendmsg got r==0!" << dendl;
     if (r < 0) {
       r = -errno; 
       ldout(msgr->cct,1) << "do_sendmsg error " << cpp_strerror(r) << dendl;
-      restore_sigpipe();
       return r;
     }
     if (state == STATE_CLOSED) {
       ldout(msgr->cct,10) << "do_sendmsg oh look, state == CLOSED, giving up" << dendl;
-      restore_sigpipe();
       return -EINTR; // close enough
     }
 
@@ -2370,7 +2299,6 @@ int Pipe::do_sendmsg(struct msghdr *msg, unsigned len, bool more)
       }
     }
   }
-  restore_sigpipe();
   return 0;
 }
 
@@ -2737,15 +2665,8 @@ int Pipe::tcp_write(const char *buf, unsigned len)
 
   //lgeneric_dout(cct, DBL) << "tcp_write writing " << len << dendl;
   assert(len > 0);
-  suppress_sigpipe();
-
   while (len > 0) {
-    int did;
-#if defined(MSG_NOSIGNAL)
-    did = ::send( sd, buf, len, MSG_NOSIGNAL );
-#else
-    did = ::send( sd, buf, len, 0);
-#endif
+    int did = ::send( sd, buf, len, MSG_NOSIGNAL );
     if (did < 0) {
       //lgeneric_dout(cct, 1) << "tcp_write error did = " << did << " " << cpp_strerror(errno) << dendl;
       //lgeneric_derr(cct, 1) << "tcp_write error did = " << did << " " << cpp_strerror(errno) << dendl;
@@ -2755,7 +2676,5 @@ int Pipe::tcp_write(const char *buf, unsigned len)
     buf += did;
     //lgeneric_dout(cct, DBL) << "tcp_write did " << did << ", " << len << " left" << dendl;
   }
-  restore_sigpipe();
-
   return 0;
 }
index 9dd00d1b48f345f0d4782798516c300246db14a0..d8d2a8e0831db13e0fdd672db8e4f0672ff60344 100644 (file)
@@ -115,11 +115,6 @@ static const int SM_IOV_MAX = (IOV_MAX >= 1024 ? IOV_MAX / 4 : IOV_MAX);
   private:
     int sd;
     struct iovec msgvec[SM_IOV_MAX];
-#if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
-    sigset_t sigpipe_mask;
-    bool sigpipe_pending;
-    bool sigpipe_unblock;
-#endif
 
   public:
     int port;
@@ -188,10 +183,6 @@ static const int SM_IOV_MAX = (IOV_MAX >= 1024 ? IOV_MAX / 4 : IOV_MAX);
     int write_keepalive();
     int write_keepalive2(char tag, const utime_t &t);
 
-    void suppress_sigpipe();
-    void restore_sigpipe();
-
-
     void fault(bool reader=false);
 
     void was_session_reset();