ultrabug    14/06/16 09:56:00

  Added:                3.0.5-fix_ucast.patch
  Log:
  fix #486186
  
  (Portage version: 2.2.10/cvs/Linux x86_64, signed Manifest commit with key 
B658FA13)

Revision  Changes    Path
1.1                  sys-cluster/heartbeat/files/3.0.5-fix_ucast.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/heartbeat/files/3.0.5-fix_ucast.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/heartbeat/files/3.0.5-fix_ucast.patch?rev=1.1&content-type=text/plain

Index: 3.0.5-fix_ucast.patch
===================================================================

# HG changeset patch
# User Lars Ellenberg <l...@linbit.com>
# Date 1392200751 -3600
# Node ID 37f57a36a2dd1abf8461a9b758e62f6fe7a22f77
# Parent  6d4324633600dc7ae7aa08c56d86c2fcc767977f
Medium: fix usage of SO_REUSEPORT in ucast sockets

Linux learned SO_REUSEPORT only with kernel 3.9,
but some linux headers already define SO_REUSEPORT.
Which, on older kernels, will result in ENOPROTOOPT,
"Protocol not available".

Failure to set SO_REUSEPORT is NOT critical in general.
It *may* be a problem on certain BSDs,
with more than two nodes, all using ucast.

Refusing to start because of failure to set SO_REUSEPORT is
not helpful for the vast majority of the clusters out there.

While at it, downgrade "critical" log messages to warnings
in non-fatal situations.

--- a/lib/plugins/HBcomm/ucast.c
+++ b/lib/plugins/HBcomm/ucast.c
@@ -461,12 +461,6 @@ static int HB_make_send_sock(struct hb_m
        int sockfd;
        struct ip_private *ei;
        int tos;
-#if defined(SO_BINDTODEVICE)
-       struct ifreq i;
-#endif
-#if defined(SO_REUSEPORT)
-       int i = 1;
-#endif
 
        UCASTASSERT(mp);
        ei = (struct ip_private*)mp->pd;
@@ -494,6 +488,7 @@ static int HB_make_send_sock(struct hb_m
 
 #if defined(SO_BINDTODEVICE)
        {
+               struct ifreq i;
                /*
                 *  We want to send out this particular interface
                 *
@@ -515,12 +510,13 @@ static int HB_make_send_sock(struct hb_m
 #endif
 #if defined(SO_REUSEPORT)
        {
+               int one = 1;
                /* this is for OpenBSD to allow multiple *
                *  ucast connections, e.g. a more than   *
                *  two node cluster                      */
 
                if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
-                               &i, sizeof(i)) == -1) {
+                               &one, sizeof(one)) == -1) {
                        PILCallLog(LOG, PIL_CRIT,
                          "ucast: error setting option SO_REUSEPORT(w): %s", 
strerror(errno));
                        close(sockfd);
@@ -548,7 +544,7 @@ static int HB_make_receive_sock(struct h
        int sockfd;
        int bindtries;
        int boundyet = 0;
-       int j;
+       int one = 1;
 
        UCASTASSERT(mp);
        ei = (struct ip_private*)mp->pd;
@@ -563,22 +559,19 @@ static int HB_make_receive_sock(struct h
                        strerror(errno));
                return -1;
        }
-       /* 
-        * Set SO_REUSEADDR on the server socket s. Variable j is used
-        * as a scratch varable.
-        *
-        * 16th February 2000
-        * Added by Horms <ho...@vergenet.net>
-        * with thanks to Clinton Work <w...@scripty.com>
-        */
-       j = 1;
+       /*
+        * Set SO_REUSEADDR on the server socket s.
+        * Below, also try to set SO_REUSEPORT,
+        * if known and supported.
+        */
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
-                       (void *)&j, sizeof j) < 0) {
+                       &one, sizeof(one)) < 0) {
                /* Ignore it.  It will almost always be OK anyway. */
-               PILCallLog(LOG, PIL_CRIT,
+               PILCallLog(LOG, PIL_WARN,
                        "ucast: error setting socket option SO_REUSEADDR: %s",
                        strerror(errno));
-       }        
+       } else
+               PILCallLog(LOG, PIL_INFO, "ucast: set SO_REUSEADDR");
 #if defined(SO_BINDTODEVICE)
        {
                /*
@@ -600,20 +593,32 @@ static int HB_make_receive_sock(struct h
        }
 #endif
 #if defined(SO_REUSEPORT)
-       {
+       /*
+        *  Needed for OpenBSD for more than two nodes in a ucast cluster
+        */
+       if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
+                       &one, sizeof(one)) == -1) {
                /*
-                *  Needed for OpenBSD for more than two nodes in a ucast 
cluster
+                * Linux learned SO_REUSEPORT only with kernel 3.9,
+                * but some linux headers already define SO_REUSEPORT.
+                * Which will result in ENOPROTOOPT, "Protocol not available"
+                * on older kernels.
+                * Failure to set SO_REUSEPORT is NOT critical in general.
+                * It *may* be a problem on certain BSDs with more than
+                * two nodes all using ucast.
+                * Refusing to start because of failure to set SO_REUSEPORT is
+                * not helpful for the vast majority of the clusters out there.
                 */
-               int i = 1;
-               if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
-                               &i, sizeof(i)) == -1) {
+               if (errno == ENOPROTOOPT) {
+                       PILCallLog(LOG, PIL_WARN,
+                         "ucast: error setting option SO_REUSEPORT: %s", 
strerror(errno));
+               } else {
                        PILCallLog(LOG, PIL_CRIT,
-                         "ucast: error setting option SO_REUSEPORT(r) %s", 
strerror(errno));
-                       close(sockfd);
+                         "ucast: error setting option SO_REUSEPORT: %s", 
strerror(errno));
                        return -1;
                }
-               PILCallLog(LOG, PIL_INFO, "ucast: set SO_REUSEPORT(w)");
-       }
+       } else
+               PILCallLog(LOG, PIL_INFO, "ucast: set SO_REUSEPORT");
 #endif
 
        /* Try binding a few times before giving up */





Reply via email to