1df6c8
From 2c99b7db00a6238fd43053dd672c8ce519d8fd27 Mon Sep 17 00:00:00 2001
1df6c8
From: Xavi Hernandez <xhernandez@redhat.com>
1df6c8
Date: Wed, 11 Dec 2019 18:21:14 +0100
1df6c8
Subject: [PATCH 341/344] socket: fix error handling
1df6c8
1df6c8
When __socket_proto_state_machine() detected a problem in the size of
1df6c8
the request or it couldn't allocate an iobuf of the requested size, it
1df6c8
returned -ENOMEM (-12). However the caller was expecting only -1 in
1df6c8
case of error. For this reason the error passes undetected initially,
1df6c8
adding back the socket to the epoll object. On further processing,
1df6c8
however, the error is finally detected and the connection terminated.
1df6c8
Meanwhile, another thread could receive a poll_in event from the same
1df6c8
connection, which could cause races with the connection destruction.
1df6c8
When this happened, the process crashed.
1df6c8
1df6c8
To fix this, all error detection conditions have been hardened to be
1df6c8
more strict on what is valid and what not. Also, we don't return
1df6c8
-ENOMEM anymore. We always return -1 in case of error.
1df6c8
1df6c8
An additional change has been done to prevent destruction of the
1df6c8
transport object while it may still be needed.
1df6c8
1df6c8
Upstream patch:
1df6c8
> Change-Id: I6e59cd81cbf670f7adfdde942625d4e6c3fbc82d
1df6c8
> Upstream patch link: https://review.gluster.org/c/glusterfs/+/23861
1df6c8
> Fixes: bz#1782495
1df6c8
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
1df6c8
1df6c8
Change-Id: I6e59cd81cbf670f7adfdde942625d4e6c3fbc82d
1df6c8
BUG: 1779696
1df6c8
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
1df6c8
Reviewed-on: https://code.engineering.redhat.com/gerrit/187689
1df6c8
Tested-by: RHGS Build Bot <nigelb@redhat.com>
1df6c8
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
1df6c8
---
1df6c8
 rpc/rpc-transport/socket/src/socket.c | 173 ++++++++++++++++++----------------
1df6c8
 1 file changed, 90 insertions(+), 83 deletions(-)
1df6c8
1df6c8
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
1df6c8
index bf2fa71..f54ca83 100644
1df6c8
--- a/rpc/rpc-transport/socket/src/socket.c
1df6c8
+++ b/rpc/rpc-transport/socket/src/socket.c
1df6c8
@@ -173,7 +173,7 @@ ssl_setup_connection_params(rpc_transport_t *this);
1df6c8
                                                                                \
1df6c8
         ret = __socket_readv(this, in->pending_vector, 1, &in->pending_vector, \
1df6c8
                              &in->pending_count, &bytes_read);                 \
1df6c8
-        if (ret == -1)                                                         \
1df6c8
+        if (ret < 0)                                                           \
1df6c8
             break;                                                             \
1df6c8
         __socket_proto_update_priv_after_read(priv, ret, bytes_read);          \
1df6c8
     }
1df6c8
@@ -739,7 +739,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count,
1df6c8
                 ret = sys_writev(sock, opvector, IOV_MIN(opcount));
1df6c8
             }
1df6c8
 
1df6c8
-            if (ret == 0 || (ret == -1 && errno == EAGAIN)) {
1df6c8
+            if ((ret == 0) || ((ret < 0) && (errno == EAGAIN))) {
1df6c8
                 /* done for now */
1df6c8
                 break;
1df6c8
             } else if (ret > 0)
1df6c8
@@ -754,7 +754,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count,
1df6c8
                 errno = ENODATA;
1df6c8
                 ret = -1;
1df6c8
             }
1df6c8
-            if (ret == -1 && errno == EAGAIN) {
1df6c8
+            if ((ret < 0) && (errno == EAGAIN)) {
1df6c8
                 /* done for now */
1df6c8
                 break;
1df6c8
             } else if (ret > 0)
1df6c8
@@ -770,7 +770,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count,
1df6c8
             errno = ENOTCONN;
1df6c8
             break;
1df6c8
         }
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret < 0) {
1df6c8
             if (errno == EINTR)
1df6c8
                 continue;
1df6c8
 
1df6c8
@@ -907,7 +907,7 @@ __socket_disconnect(rpc_transport_t *this)
1df6c8
     gf_log(this->name, GF_LOG_TRACE, "disconnecting %p, sock=%d", this,
1df6c8
            priv->sock);
1df6c8
 
1df6c8
-    if (priv->sock != -1) {
1df6c8
+    if (priv->sock >= 0) {
1df6c8
         gf_log_callingfn(this->name, GF_LOG_TRACE,
1df6c8
                          "tearing down socket connection");
1df6c8
         ret = __socket_teardown_connection(this);
1df6c8
@@ -942,7 +942,7 @@ __socket_server_bind(rpc_transport_t *this)
1df6c8
 
1df6c8
     ret = setsockopt(priv->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1df6c8
 
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log(this->name, GF_LOG_ERROR,
1df6c8
                "setsockopt() for SO_REUSEADDR failed (%s)", strerror(errno));
1df6c8
     }
1df6c8
@@ -955,7 +955,7 @@ __socket_server_bind(rpc_transport_t *this)
1df6c8
         if (reuse_check_sock >= 0) {
1df6c8
             ret = connect(reuse_check_sock, SA(&unix_addr),
1df6c8
                           this->myinfo.sockaddr_len);
1df6c8
-            if ((ret == -1) && (ECONNREFUSED == errno)) {
1df6c8
+            if ((ret != 0) && (ECONNREFUSED == errno)) {
1df6c8
                 sys_unlink(((struct sockaddr_un *)&unix_addr)->sun_path);
1df6c8
             }
1df6c8
             gf_log(this->name, GF_LOG_INFO,
1df6c8
@@ -967,7 +967,7 @@ __socket_server_bind(rpc_transport_t *this)
1df6c8
     ret = bind(priv->sock, (struct sockaddr *)&this->myinfo.sockaddr,
1df6c8
                this->myinfo.sockaddr_len);
1df6c8
 
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log(this->name, GF_LOG_ERROR, "binding to %s failed: %s",
1df6c8
                this->myinfo.identifier, strerror(errno));
1df6c8
         if (errno == EADDRINUSE) {
1df6c8
@@ -976,7 +976,7 @@ __socket_server_bind(rpc_transport_t *this)
1df6c8
     }
1df6c8
     if (AF_UNIX != SA(&this->myinfo.sockaddr)->sa_family) {
1df6c8
         if (getsockname(priv->sock, SA(&this->myinfo.sockaddr),
1df6c8
-                        &this->myinfo.sockaddr_len) == -1) {
1df6c8
+                        &this->myinfo.sockaddr_len) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "getsockname on (%d) failed (%s)", priv->sock,
1df6c8
                    strerror(errno));
1df6c8
@@ -1004,7 +1004,7 @@ __socket_nonblock(int fd)
1df6c8
 
1df6c8
     flags = fcntl(fd, F_GETFL);
1df6c8
 
1df6c8
-    if (flags != -1)
1df6c8
+    if (flags >= 0)
1df6c8
         ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1df6c8
 
1df6c8
     return ret;
1df6c8
@@ -1034,7 +1034,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
 #endif
1df6c8
 
1df6c8
     ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set keep alive option on socket %d", fd);
1df6c8
         goto err;
1df6c8
@@ -1051,7 +1051,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
     ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepaliveintvl,
1df6c8
                      sizeof(keepaliveintvl));
1df6c8
 #endif
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set keep alive interval on socket %d", fd);
1df6c8
         goto err;
1df6c8
@@ -1062,7 +1062,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
 
1df6c8
     ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepaliveidle,
1df6c8
                      sizeof(keepaliveidle));
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set keep idle %d on socket %d, %s", keepaliveidle, fd,
1df6c8
                strerror(errno));
1df6c8
@@ -1070,7 +1070,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
     }
1df6c8
     ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepaliveintvl,
1df6c8
                      sizeof(keepaliveintvl));
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set keep interval %d on socket %d, %s",
1df6c8
                keepaliveintvl, fd, strerror(errno));
1df6c8
@@ -1082,7 +1082,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
         goto done;
1df6c8
     ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout_ms,
1df6c8
                      sizeof(timeout_ms));
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set "
1df6c8
                "TCP_USER_TIMEOUT %d on socket %d, %s",
1df6c8
@@ -1093,7 +1093,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle,
1df6c8
 #if defined(TCP_KEEPCNT)
1df6c8
     ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepalivecnt,
1df6c8
                      sizeof(keepalivecnt));
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret != 0) {
1df6c8
         gf_log("socket", GF_LOG_WARNING,
1df6c8
                "failed to set "
1df6c8
                "TCP_KEEPCNT %d on socket %d, %s",
1df6c8
@@ -1366,7 +1366,7 @@ socket_event_poll_err(rpc_transport_t *this, int gen, int idx)
1df6c8
 
1df6c8
     pthread_mutex_lock(&priv->out_lock);
1df6c8
     {
1df6c8
-        if ((priv->gen == gen) && (priv->idx == idx) && (priv->sock != -1)) {
1df6c8
+        if ((priv->gen == gen) && (priv->idx == idx) && (priv->sock >= 0)) {
1df6c8
             __socket_ioq_flush(this);
1df6c8
             __socket_reset(this);
1df6c8
             socket_closed = _gf_true;
1df6c8
@@ -1405,7 +1405,7 @@ socket_event_poll_out(rpc_transport_t *this)
1df6c8
         if (priv->connected == 1) {
1df6c8
             ret = __socket_ioq_churn(this);
1df6c8
 
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret < 0) {
1df6c8
                 gf_log(this->name, GF_LOG_TRACE,
1df6c8
                        "__socket_ioq_churn returned -1; "
1df6c8
                        "disconnecting socket");
1df6c8
@@ -1463,7 +1463,7 @@ __socket_read_simple_msg(rpc_transport_t *this)
1df6c8
                                      &bytes_read);
1df6c8
             }
1df6c8
 
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret < 0) {
1df6c8
                 gf_log(this->name, GF_LOG_WARNING,
1df6c8
                        "reading from socket failed. Error (%s), "
1df6c8
                        "peer (%s)",
1df6c8
@@ -1661,8 +1661,8 @@ __socket_read_vectored_request(rpc_transport_t *this,
1df6c8
 
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
 
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                RPC_LASTFRAG(in->fraghdr))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              RPC_LASTFRAG(in->fraghdr))) {
1df6c8
                 request->vector_state = SP_STATE_VECTORED_REQUEST_INIT;
1df6c8
                 in->payload_vector.iov_len = ((unsigned long)frag->fragcurrent -
1df6c8
                                               (unsigned long)
1df6c8
@@ -1739,8 +1739,8 @@ __socket_read_request(rpc_transport_t *this)
1df6c8
 
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
 
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
                 request->header_state = SP_STATE_REQUEST_HEADER_INIT;
1df6c8
             }
1df6c8
 
1df6c8
@@ -1870,8 +1870,8 @@ __socket_read_accepted_successful_reply(rpc_transport_t *this)
1df6c8
             /* now read the entire remaining msg into new iobuf */
1df6c8
             ret = __socket_read_simple_msg(this);
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                RPC_LASTFRAG(in->fraghdr))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              RPC_LASTFRAG(in->fraghdr))) {
1df6c8
                 frag->call_body.reply.accepted_success_state =
1df6c8
                     SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT;
1df6c8
             }
1df6c8
@@ -2003,8 +2003,8 @@ __socket_read_accepted_successful_reply_v2(rpc_transport_t *this)
1df6c8
             /* now read the entire remaining msg into new iobuf */
1df6c8
             ret = __socket_read_simple_msg(this);
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                RPC_LASTFRAG(in->fraghdr))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              RPC_LASTFRAG(in->fraghdr))) {
1df6c8
                 frag->call_body.reply.accepted_success_state =
1df6c8
                     SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT;
1df6c8
             }
1df6c8
@@ -2103,8 +2103,8 @@ __socket_read_accepted_reply(rpc_transport_t *this)
1df6c8
 
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
 
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
                 frag->call_body.reply
1df6c8
                     .accepted_state = SP_STATE_ACCEPTED_REPLY_INIT;
1df6c8
             }
1df6c8
@@ -2169,8 +2169,8 @@ __socket_read_vectored_reply(rpc_transport_t *this)
1df6c8
 
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
 
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
                 frag->call_body.reply
1df6c8
                     .status_state = SP_STATE_VECTORED_REPLY_STATUS_INIT;
1df6c8
                 in->payload_vector.iov_len = (unsigned long)frag->fragcurrent -
1df6c8
@@ -2237,7 +2237,7 @@ __socket_read_reply(rpc_transport_t *this)
1df6c8
         /* Transition back to externally visible state. */
1df6c8
         frag->state = SP_STATE_READ_MSGTYPE;
1df6c8
 
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret < 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "notify for event MAP_XID failed for %s",
1df6c8
                    this->peerinfo.identifier);
1df6c8
@@ -2315,8 +2315,8 @@ __socket_read_frag(rpc_transport_t *this)
1df6c8
 
1df6c8
             remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read;
1df6c8
 
1df6c8
-            if ((ret == -1) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
-                                (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
+            if ((ret < 0) || ((ret == 0) && (remaining_size == 0) &&
1df6c8
+                              (RPC_LASTFRAG(in->fraghdr)))) {
1df6c8
                 /* frag->state = SP_STATE_NADA; */
1df6c8
                 frag->state = SP_STATE_RPCFRAG_INIT;
1df6c8
             }
1df6c8
@@ -2400,7 +2400,7 @@ __socket_proto_state_machine(rpc_transport_t *this,
1df6c8
                 ret = __socket_readv(this, in->pending_vector, 1,
1df6c8
                                      &in->pending_vector, &in->pending_count,
1df6c8
                                      NULL);
1df6c8
-                if (ret == -1)
1df6c8
+                if (ret < 0)
1df6c8
                     goto out;
1df6c8
 
1df6c8
                 if (ret > 0) {
1df6c8
@@ -2422,7 +2422,7 @@ __socket_proto_state_machine(rpc_transport_t *this,
1df6c8
                 in->total_bytes_read += RPC_FRAGSIZE(in->fraghdr);
1df6c8
 
1df6c8
                 if (in->total_bytes_read >= GF_UNIT_GB) {
1df6c8
-                    ret = -ENOMEM;
1df6c8
+                    ret = -1;
1df6c8
                     goto out;
1df6c8
                 }
1df6c8
 
1df6c8
@@ -2430,7 +2430,7 @@ __socket_proto_state_machine(rpc_transport_t *this,
1df6c8
                     this->ctx->iobuf_pool,
1df6c8
                     (in->total_bytes_read + sizeof(in->fraghdr)));
1df6c8
                 if (!iobuf) {
1df6c8
-                    ret = -ENOMEM;
1df6c8
+                    ret = -1;
1df6c8
                     goto out;
1df6c8
                 }
1df6c8
 
1df6c8
@@ -2457,7 +2457,7 @@ __socket_proto_state_machine(rpc_transport_t *this,
1df6c8
             case SP_STATE_READING_FRAG:
1df6c8
                 ret = __socket_read_frag(this);
1df6c8
 
1df6c8
-                if ((ret == -1) ||
1df6c8
+                if ((ret < 0) ||
1df6c8
                     (frag->bytes_read != RPC_FRAGSIZE(in->fraghdr))) {
1df6c8
                     goto out;
1df6c8
                 }
1df6c8
@@ -2575,7 +2575,7 @@ socket_event_poll_in(rpc_transport_t *this, gf_boolean_t notify_handled)
1df6c8
         pthread_mutex_unlock(&priv->notify.lock);
1df6c8
     }
1df6c8
 
1df6c8
-    if (notify_handled && (ret != -1))
1df6c8
+    if (notify_handled && (ret >= 0))
1df6c8
         event_handled(ctx->event_pool, priv->sock, priv->idx, priv->gen);
1df6c8
 
1df6c8
     if (pollin) {
1df6c8
@@ -2618,10 +2618,10 @@ socket_connect_finish(rpc_transport_t *this)
1df6c8
 
1df6c8
         ret = __socket_connect_finish(priv->sock);
1df6c8
 
1df6c8
-        if (ret == -1 && errno == EINPROGRESS)
1df6c8
+        if ((ret < 0) && (errno == EINPROGRESS))
1df6c8
             ret = 1;
1df6c8
 
1df6c8
-        if (ret == -1 && errno != EINPROGRESS) {
1df6c8
+        if ((ret < 0) && (errno != EINPROGRESS)) {
1df6c8
             if (!priv->connect_finish_log) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "connection to %s failed (%s); "
1df6c8
@@ -2640,7 +2640,7 @@ socket_connect_finish(rpc_transport_t *this)
1df6c8
 
1df6c8
             ret = getsockname(priv->sock, SA(&this->myinfo.sockaddr),
1df6c8
                               &this->myinfo.sockaddr_len);
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_WARNING,
1df6c8
                        "getsockname on (%d) failed (%s) - "
1df6c8
                        "disconnecting socket",
1df6c8
@@ -2924,6 +2924,13 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
         return;
1df6c8
     }
1df6c8
 
1df6c8
+    /* At this point we are sure no other thread is using the transport because
1df6c8
+     * we cannot receive more events until we call gf_event_handled(). However
1df6c8
+     * this function may call gf_event_handled() in some cases. When this is
1df6c8
+     * done, the transport may be destroyed at any moment if another thread
1df6c8
+     * handled an error event. To prevent that we take a reference here. */
1df6c8
+    rpc_transport_ref(this);
1df6c8
+
1df6c8
     GF_VALIDATE_OR_GOTO("socket", this, out);
1df6c8
     GF_VALIDATE_OR_GOTO("socket", this->private, out);
1df6c8
     GF_VALIDATE_OR_GOTO("socket", this->xl, out);
1df6c8
@@ -2960,7 +2967,7 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
             if (ret > 0) {
1df6c8
                 gf_log(this->name, GF_LOG_TRACE,
1df6c8
                        "(sock:%d) returning to wait on socket", priv->sock);
1df6c8
-                return;
1df6c8
+                goto out;
1df6c8
             }
1df6c8
         } else {
1df6c8
             char *sock_type = (priv->is_server ? "Server" : "Client");
1df6c8
@@ -3015,7 +3022,7 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
     }
1df6c8
 
1df6c8
 out:
1df6c8
-    return;
1df6c8
+    rpc_transport_unref(this);
1df6c8
 }
1df6c8
 
1df6c8
 static void
1df6c8
@@ -3074,7 +3081,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
 
1df6c8
         event_handled(ctx->event_pool, fd, idx, gen);
1df6c8
 
1df6c8
-        if (new_sock == -1) {
1df6c8
+        if (new_sock < 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING, "accept on %d failed (%s)",
1df6c8
                    priv->sock, strerror(errno));
1df6c8
             goto out;
1df6c8
@@ -3082,7 +3089,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
 
1df6c8
         if (priv->nodelay && (new_sockaddr.ss_family != AF_UNIX)) {
1df6c8
             ret = __socket_nodelay(new_sock);
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_WARNING,
1df6c8
                        "setsockopt() failed for "
1df6c8
                        "NODELAY (%s)",
1df6c8
@@ -3094,7 +3101,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
             ret = __socket_keepalive(new_sock, new_sockaddr.ss_family,
1df6c8
                                      priv->keepaliveintvl, priv->keepaliveidle,
1df6c8
                                      priv->keepalivecnt, priv->timeout);
1df6c8
-            if (ret == -1)
1df6c8
+            if (ret != 0)
1df6c8
                 gf_log(this->name, GF_LOG_WARNING,
1df6c8
                        "Failed to set keep-alive: %s", strerror(errno));
1df6c8
         }
1df6c8
@@ -3110,7 +3117,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
         }
1df6c8
 
1df6c8
         ret = pthread_mutex_init(&new_trans->lock, NULL);
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret != 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "pthread_mutex_init() failed: %s; closing newly accepted "
1df6c8
                    "socket %d",
1df6c8
@@ -3130,7 +3137,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
 
1df6c8
         ret = getsockname(new_sock, SA(&new_trans->myinfo.sockaddr),
1df6c8
                           &new_trans->myinfo.sockaddr_len);
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret != 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "getsockname on socket %d "
1df6c8
                    "failed (errno:%s); closing newly accepted socket",
1df6c8
@@ -3237,7 +3244,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
              */
1df6c8
             ret = rpc_transport_notify(this, RPC_TRANSPORT_ACCEPT, new_trans);
1df6c8
 
1df6c8
-            if (ret != -1) {
1df6c8
+            if (ret >= 0) {
1df6c8
                 new_priv->idx = event_register(
1df6c8
                     ctx->event_pool, new_sock, socket_event_handler, new_trans,
1df6c8
                     1, 0, new_trans->notify_poller_death);
1df6c8
@@ -3275,7 +3282,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in,
1df6c8
             rpc_transport_unref(new_trans);
1df6c8
         }
1df6c8
 
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret < 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING, "closing newly accepted socket");
1df6c8
             sys_close(new_sock);
1df6c8
             /* this unref is to actually cause the destruction of
1df6c8
@@ -3406,7 +3413,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
 
1df6c8
     pthread_mutex_lock(&priv->out_lock);
1df6c8
     {
1df6c8
-        if (priv->sock != -1) {
1df6c8
+        if (priv->sock >= 0) {
1df6c8
             gf_log_callingfn(this->name, GF_LOG_TRACE,
1df6c8
                              "connect () called on transport "
1df6c8
                              "already connected");
1df6c8
@@ -3420,7 +3427,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
 
1df6c8
         ret = socket_client_get_remote_sockaddr(this, &sock_union.sa,
1df6c8
                                                 &sockaddr_len, &sa_family);
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret < 0) {
1df6c8
             /* logged inside client_get_remote_sockaddr */
1df6c8
             goto unlock;
1df6c8
         }
1df6c8
@@ -3439,7 +3446,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
         this->peerinfo.sockaddr_len = sockaddr_len;
1df6c8
 
1df6c8
         priv->sock = sys_socket(sa_family, SOCK_STREAM, 0);
1df6c8
-        if (priv->sock == -1) {
1df6c8
+        if (priv->sock < 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR, "socket creation failed (%s)",
1df6c8
                    strerror(errno));
1df6c8
             ret = -1;
1df6c8
@@ -3451,7 +3458,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
          */
1df6c8
         if (priv->windowsize != 0) {
1df6c8
             if (setsockopt(priv->sock, SOL_SOCKET, SO_RCVBUF, &priv->windowsize,
1df6c8
-                           sizeof(priv->windowsize)) < 0) {
1df6c8
+                           sizeof(priv->windowsize)) != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "setting receive window "
1df6c8
                        "size failed: %d: %d: %s",
1df6c8
@@ -3459,7 +3466,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
             }
1df6c8
 
1df6c8
             if (setsockopt(priv->sock, SOL_SOCKET, SO_SNDBUF, &priv->windowsize,
1df6c8
-                           sizeof(priv->windowsize)) < 0) {
1df6c8
+                           sizeof(priv->windowsize)) != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "setting send window size "
1df6c8
                        "failed: %d: %d: %s",
1df6c8
@@ -3484,7 +3491,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
         if (priv->nodelay && (sa_family != AF_UNIX)) {
1df6c8
             ret = __socket_nodelay(priv->sock);
1df6c8
 
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR, "NODELAY on %d failed (%s)",
1df6c8
                        priv->sock, strerror(errno));
1df6c8
             }
1df6c8
@@ -3494,7 +3501,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
             ret = __socket_keepalive(priv->sock, sa_family,
1df6c8
                                      priv->keepaliveintvl, priv->keepaliveidle,
1df6c8
                                      priv->keepalivecnt, priv->timeout);
1df6c8
-            if (ret == -1)
1df6c8
+            if (ret != 0)
1df6c8
                 gf_log(this->name, GF_LOG_ERROR, "Failed to set keep-alive: %s",
1df6c8
                        strerror(errno));
1df6c8
         }
1df6c8
@@ -3516,7 +3523,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
 
1df6c8
         ret = client_bind(this, SA(&this->myinfo.sockaddr),
1df6c8
                           &this->myinfo.sockaddr_len, priv->sock);
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret < 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING, "client bind failed: %s",
1df6c8
                    strerror(errno));
1df6c8
             goto handler;
1df6c8
@@ -3525,7 +3532,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
         /* make socket non-blocking for all types of sockets */
1df6c8
         if (!priv->bio) {
1df6c8
             ret = __socket_nonblock(priv->sock);
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR, "NBIO on %d failed (%s)",
1df6c8
                        priv->sock, strerror(errno));
1df6c8
                 goto handler;
1df6c8
@@ -3552,7 +3559,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
 
1df6c8
         connect_attempted = _gf_true;
1df6c8
 
1df6c8
-        if (ret == -1 && errno == ENOENT && ign_enoent) {
1df6c8
+        if ((ret != 0) && (errno == ENOENT) && ign_enoent) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "Ignore failed connection attempt on %s, (%s) ",
1df6c8
                    this->peerinfo.identifier, strerror(errno));
1df6c8
@@ -3570,7 +3577,7 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
             goto handler;
1df6c8
         }
1df6c8
 
1df6c8
-        if (ret == -1 && ((errno != EINPROGRESS) && (errno != ENOENT))) {
1df6c8
+        if ((ret != 0) && (errno != EINPROGRESS) && (errno != ENOENT)) {
1df6c8
             /* For unix path based sockets, the socket path is
1df6c8
              * cryptic (md5sum of path) and may not be useful for
1df6c8
              * the user in debugging so log it in DEBUG
1df6c8
@@ -3634,8 +3641,8 @@ socket_connect(rpc_transport_t *this, int port)
1df6c8
     pthread_mutex_unlock(&priv->out_lock);
1df6c8
 
1df6c8
 err:
1df6c8
-    /* if sock != -1, then cleanup is done from the event handler */
1df6c8
-    if (ret == -1 && sock == -1) {
1df6c8
+    /* if sock >= 0, then cleanup is done from the event handler */
1df6c8
+    if ((ret < 0) && (sock < 0)) {
1df6c8
         /* Cleaup requires to send notification to upper layer which
1df6c8
            intern holds the big_lock. There can be dead-lock situation
1df6c8
            if big_lock is already held by the current thread.
1df6c8
@@ -3689,20 +3696,20 @@ socket_listen(rpc_transport_t *this)
1df6c8
     }
1df6c8
     pthread_mutex_unlock(&priv->out_lock);
1df6c8
 
1df6c8
-    if (sock != -1) {
1df6c8
+    if (sock >= 0) {
1df6c8
         gf_log_callingfn(this->name, GF_LOG_DEBUG, "already listening");
1df6c8
         return ret;
1df6c8
     }
1df6c8
 
1df6c8
     ret = socket_server_get_local_sockaddr(this, SA(&sockaddr), &sockaddr_len,
1df6c8
                                            &sa_family);
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret < 0) {
1df6c8
         return ret;
1df6c8
     }
1df6c8
 
1df6c8
     pthread_mutex_lock(&priv->out_lock);
1df6c8
     {
1df6c8
-        if (priv->sock != -1) {
1df6c8
+        if (priv->sock >= 0) {
1df6c8
             gf_log(this->name, GF_LOG_DEBUG, "already listening");
1df6c8
             goto unlock;
1df6c8
         }
1df6c8
@@ -3712,7 +3719,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
 
1df6c8
         priv->sock = sys_socket(sa_family, SOCK_STREAM, 0);
1df6c8
 
1df6c8
-        if (priv->sock == -1) {
1df6c8
+        if (priv->sock < 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR, "socket creation failed (%s)",
1df6c8
                    strerror(errno));
1df6c8
             goto unlock;
1df6c8
@@ -3723,7 +3730,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
          */
1df6c8
         if (priv->windowsize != 0) {
1df6c8
             if (setsockopt(priv->sock, SOL_SOCKET, SO_RCVBUF, &priv->windowsize,
1df6c8
-                           sizeof(priv->windowsize)) < 0) {
1df6c8
+                           sizeof(priv->windowsize)) != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "setting receive window size "
1df6c8
                        "failed: %d: %d: %s",
1df6c8
@@ -3731,7 +3738,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
             }
1df6c8
 
1df6c8
             if (setsockopt(priv->sock, SOL_SOCKET, SO_SNDBUF, &priv->windowsize,
1df6c8
-                           sizeof(priv->windowsize)) < 0) {
1df6c8
+                           sizeof(priv->windowsize)) != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "setting send window size failed:"
1df6c8
                        " %d: %d: %s",
1df6c8
@@ -3741,7 +3748,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
 
1df6c8
         if (priv->nodelay && (sa_family != AF_UNIX)) {
1df6c8
             ret = __socket_nodelay(priv->sock);
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "setsockopt() failed for NODELAY (%s)", strerror(errno));
1df6c8
             }
1df6c8
@@ -3750,7 +3757,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
         if (!priv->bio) {
1df6c8
             ret = __socket_nonblock(priv->sock);
1df6c8
 
1df6c8
-            if (ret == -1) {
1df6c8
+            if (ret != 0) {
1df6c8
                 gf_log(this->name, GF_LOG_ERROR,
1df6c8
                        "NBIO on socket %d failed "
1df6c8
                        "(errno:%s); closing socket",
1df6c8
@@ -3763,7 +3770,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
 
1df6c8
         ret = __socket_server_bind(this);
1df6c8
 
1df6c8
-        if ((ret == -EADDRINUSE) || (ret == -1)) {
1df6c8
+        if (ret < 0) {
1df6c8
             /* logged inside __socket_server_bind() */
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "__socket_server_bind failed;"
1df6c8
@@ -3779,7 +3786,7 @@ socket_listen(rpc_transport_t *this)
1df6c8
 
1df6c8
         ret = listen(priv->sock, priv->backlog);
1df6c8
 
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "could not set socket %d to listen mode (errno:%s); "
1df6c8
                    "closing socket",
1df6c8
@@ -4025,7 +4032,7 @@ reconfigure(rpc_transport_t *this, dict_t *options)
1df6c8
     priv = this->private;
1df6c8
 
1df6c8
     if (dict_get_str(options, "transport.socket.keepalive", &optstr) == 0) {
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "'transport.socket.keepalive' takes only "
1df6c8
                    "boolean options, not taking any action");
1df6c8
@@ -4094,7 +4101,7 @@ reconfigure(rpc_transport_t *this, dict_t *options)
1df6c8
     if (dict_get(options, "non-blocking-io")) {
1df6c8
         optstr = data_to_str(dict_get(options, "non-blocking-io"));
1df6c8
 
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "'non-blocking-io' takes only boolean options,"
1df6c8
                    " not taking any action");
1df6c8
@@ -4109,7 +4116,7 @@ reconfigure(rpc_transport_t *this, dict_t *options)
1df6c8
 
1df6c8
     if (!priv->bio) {
1df6c8
         ret = __socket_nonblock(priv->sock);
1df6c8
-        if (ret == -1) {
1df6c8
+        if (ret != 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING, "NBIO on %d failed (%s)",
1df6c8
                    priv->sock, strerror(errno));
1df6c8
             goto out;
1df6c8
@@ -4508,7 +4515,7 @@ socket_init(rpc_transport_t *this)
1df6c8
     if (dict_get(this->options, "non-blocking-io")) {
1df6c8
         optstr = data_to_str(dict_get(this->options, "non-blocking-io"));
1df6c8
 
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "'non-blocking-io' takes only boolean options,"
1df6c8
                    " not taking any action");
1df6c8
@@ -4528,7 +4535,7 @@ socket_init(rpc_transport_t *this)
1df6c8
         optstr = data_to_str(
1df6c8
             dict_get(this->options, "transport.socket.nodelay"));
1df6c8
 
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "'transport.socket.nodelay' takes only "
1df6c8
                    "boolean options, not taking any action");
1df6c8
@@ -4559,7 +4566,7 @@ socket_init(rpc_transport_t *this)
1df6c8
     priv->keepalivecnt = GF_KEEPALIVE_COUNT;
1df6c8
     if (dict_get_str(this->options, "transport.socket.keepalive", &optstr) ==
1df6c8
         0) {
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_ERROR,
1df6c8
                    "'transport.socket.keepalive' takes only "
1df6c8
                    "boolean options, not taking any action");
1df6c8
@@ -4609,7 +4616,7 @@ socket_init(rpc_transport_t *this)
1df6c8
     if (dict_get(this->options, "transport.socket.read-fail-log")) {
1df6c8
         optstr = data_to_str(
1df6c8
             dict_get(this->options, "transport.socket.read-fail-log"));
1df6c8
-        if (gf_string2boolean(optstr, &tmp_bool) == -1) {
1df6c8
+        if (gf_string2boolean(optstr, &tmp_bool) != 0) {
1df6c8
             gf_log(this->name, GF_LOG_WARNING,
1df6c8
                    "'transport.socket.read-fail-log' takes only "
1df6c8
                    "boolean options; logging socket read fails");
1df6c8
@@ -4646,7 +4653,7 @@ fini(rpc_transport_t *this)
1df6c8
 
1df6c8
     priv = this->private;
1df6c8
     if (priv) {
1df6c8
-        if (priv->sock != -1) {
1df6c8
+        if (priv->sock >= 0) {
1df6c8
             pthread_mutex_lock(&priv->out_lock);
1df6c8
             {
1df6c8
                 __socket_ioq_flush(this);
1df6c8
@@ -4683,7 +4690,7 @@ init(rpc_transport_t *this)
1df6c8
 
1df6c8
     ret = socket_init(this);
1df6c8
 
1df6c8
-    if (ret == -1) {
1df6c8
+    if (ret < 0) {
1df6c8
         gf_log(this->name, GF_LOG_DEBUG, "socket_init() failed");
1df6c8
     }
1df6c8
 
1df6c8
-- 
1df6c8
1.8.3.1
1df6c8