diff options
Diffstat (limited to 'rpc')
| -rw-r--r-- | rpc/rpc-transport/socket/src/socket.c | 88 | ||||
| -rw-r--r-- | rpc/rpc-transport/socket/src/socket.h | 3 | 
2 files changed, 91 insertions, 0 deletions
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 17c66d9a374..0f0825be8ae 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -361,6 +361,46 @@ __socket_nodelay (int fd)          return ret;  } + +static int +__socket_keepalive (int fd, int keepalive_intvl) +{ +        int     on = 1; +        int     ret = -1; + +        ret = setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)); +        if (ret == -1) +                goto err; + +        if (keepalive_intvl == GF_USE_DEFAULT_KEEPALIVE) +                goto done; + +#ifndef GF_LINUX_HOST_OS +        ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepalive_intvl, +                          sizeof (keepalive_intvl)); +        if (ret == -1) +                goto err; +#else +        ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_intvl, +                          sizeof (keepalive_intvl)); +        if (ret == -1) +                goto err; + +        ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl, +                          sizeof (keepalive_intvl)); +        if (ret == -1) +                goto err; +#endif + +done: +        gf_log ("", GF_LOG_TRACE, "Keep-alive enabled for socket %d, interval " +                "%d", fd, keepalive_intvl); + +err: +        return ret; +} + +  int  __socket_connect_finish (int fd)  { @@ -1760,6 +1800,15 @@ socket_server_event_handler (int fd, int idx, void *data,                                  }                          } +                        if (priv->keepalive) { +                                ret = __socket_keepalive (new_sock, +                                                          priv->keepaliveintvl); +                                if (ret == -1) +                                        gf_log (this->name, GF_LOG_ERROR, +                                                "Failed to set keep-alive: %s", +                                                strerror (errno)); +                        } +                          new_trans = GF_CALLOC (1, sizeof (*new_trans),                                                 gf_common_mt_rpc_trans_t);                          if (!new_trans) @@ -1959,6 +2008,15 @@ socket_connect (rpc_transport_t *this, int port)                          }                  } +                if (priv->keepalive) { +                        ret = __socket_keepalive (priv->sock, +                                                  priv->keepaliveintvl); +                        if (ret == -1) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "Failed to set keep-alive: %s", +                                        strerror (errno)); +                } +                  SA (&this->myinfo.sockaddr)->sa_family =  			SA (&this->peerinfo.sockaddr)->sa_family; @@ -2372,6 +2430,7 @@ socket_init (rpc_transport_t *this)          gf_boolean_t      tmp_bool = 0;          uint64_t          windowsize = GF_DEFAULT_SOCKET_WINDOW_SIZE;          char             *optstr = NULL; +        uint32_t          keepalive = 0;          if (this->private) {                  gf_log (this->name, GF_LOG_DEBUG, @@ -2412,6 +2471,7 @@ socket_init (rpc_transport_t *this)  				" not taking any action");                          tmp_bool = 1;                  } +                  if (!tmp_bool) {                          priv->bio = 1;                          gf_log (this->name, GF_LOG_WARNING, @@ -2457,6 +2517,28 @@ socket_init (rpc_transport_t *this)                  priv->lowlat = 1;          } +        /* Enable Keep-alive by default. */ +        priv->keepalive = 1; +        priv->keepaliveintvl = GF_USE_DEFAULT_KEEPALIVE; +        if (dict_get_str (this->options, "transport.socket.keepalive", +                          &optstr) == 0) { +                if (gf_string2boolean (optstr, &tmp_bool) == -1) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "'transport.socket.keepalive' takes only " +                                 "boolean options, not taking any action"); +                        tmp_bool = 1; +                } + +                if (!tmp_bool) +                        priv->keepalive = 0; +        } + +        if (dict_get_uint32 (this->options, +                             "transport.socket.keepalive-interval", +                             &keepalive) == 0) { +                priv->keepaliveintvl = keepalive; +        } +          priv->windowsize = (int)windowsize;  out:          this->private = priv; @@ -2550,5 +2632,11 @@ struct volume_options options[] = {          { .key   = {"transport.socket.lowlat"},            .type  = GF_OPTION_TYPE_BOOL          }, +        { .key   = {"transport.socket.keepalive"}, +          .type  = GF_OPTION_TYPE_BOOL +        }, +        { .key   = {"transport.socket.keepalive-interval"}, +          .type  = GF_OPTION_TYPE_INT +        },          { .key = {NULL} }  }; diff --git a/rpc/rpc-transport/socket/src/socket.h b/rpc/rpc-transport/socket/src/socket.h index 44acc66a0a5..f7471ffb85c 100644 --- a/rpc/rpc-transport/socket/src/socket.h +++ b/rpc/rpc-transport/socket/src/socket.h @@ -53,6 +53,7 @@  #define GF_DEFAULT_SOCKET_WINDOW_SIZE   (512 * GF_UNIT_KB)  #define GF_MAX_SOCKET_WINDOW_SIZE       (1 * GF_UNIT_MB)  #define GF_MIN_SOCKET_WINDOW_SIZE       (128 * GF_UNIT_KB) +#define GF_USE_DEFAULT_KEEPALIVE        (-1)  typedef enum {          SP_STATE_NADA = 0, @@ -187,6 +188,8 @@ typedef struct {          int                    windowsize;          char                   lowlat;          char                   nodelay; +        int                    keepalive; +        int                    keepaliveintvl;  } socket_private_t;  | 
