diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2010-05-18 02:20:17 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-05-21 00:32:27 -0700 | 
| commit | c0763ba1579fbad705cd29e256fb083376fb0e07 (patch) | |
| tree | 3f14f1096ca2c59be356967466907360475395b6 | |
| parent | 608223c792fc308729b522777efad4c6afb8238c (diff) | |
socket: Support TCP-KEEPALIVE
Introduces two new socket options:
1. transport.socket.keepalive: bool
Sets keepalive on a transport. On by default.
2. transport.socket.keepalive-interval: integer
Number of seconds between each keepalive message on the socket.
Default in linux is 2 hours. To change that value for a given
transport, use this option. Integer value is interval in seconds.
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 754 (enable tcp keepalive)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=754
| -rw-r--r-- | transport/socket/src/socket.c | 80 | ||||
| -rw-r--r-- | transport/socket/src/socket.h | 4 | 
2 files changed, 84 insertions, 0 deletions
diff --git a/transport/socket/src/socket.c b/transport/socket/src/socket.c index 28b828f29a2..4d4b01b5cf8 100644 --- a/transport/socket/src/socket.c +++ b/transport/socket/src/socket.c @@ -245,6 +245,38 @@ __socket_nodelay (int fd)          return ret;  } + +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; + +        ret = setsockopt (fd, SOL_TCP, TCP_KEEPIDLE, &keepalive_intvl, +                          sizeof (keepalive_intvl)); +        if (ret == -1) +                goto err; + +        ret = setsockopt (fd, SOL_TCP, TCP_KEEPINTVL, &keepalive_intvl, +                          sizeof (keepalive_intvl)); +        if (ret == -1) +                goto err; +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)  { @@ -891,6 +923,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->xl->name, GF_LOG_ERROR, +                                                "Failed to set keep-alive: %s", +                                                strerror (errno)); +                        } +                          new_trans = CALLOC (1, sizeof (*new_trans));                          new_trans->xl = this->xl;                          new_trans->fini = this->fini; @@ -1067,6 +1108,15 @@ socket_connect (transport_t *this)                          }                  } +                if (priv->keepalive) { +                        ret = __socket_keepalive (priv->sock, +                                                  priv->keepaliveintvl); +                        if (ret == -1) +                                gf_log (this->xl->name, GF_LOG_ERROR, +                                        "Failed to set keep-alive: %s", +                                        strerror (errno)); +                } +                  SA (&this->myinfo.sockaddr)->sa_family =  			SA (&this->peerinfo.sockaddr)->sa_family; @@ -1369,6 +1419,7 @@ socket_init (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->xl->name, GF_LOG_DEBUG, @@ -1449,6 +1500,29 @@ socket_init (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->xl->options, "transport.socket.keepalive", +                          &optstr) == 0) { +                if (gf_string2boolean (optstr, &tmp_bool) == -1) { +                        gf_log (this->xl->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->xl->options, +                             "transport.socket.keepalive-interval", +                             &keepalive) == 0) { +                priv->keepaliveintvl = keepalive; +        } +          priv->windowsize = (int)windowsize;          this->private = priv; @@ -1525,6 +1599,12 @@ 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/transport/socket/src/socket.h b/transport/socket/src/socket.h index 44715697db1..5a287a72c98 100644 --- a/transport/socket/src/socket.h +++ b/transport/socket/src/socket.h @@ -52,6 +52,8 @@  #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 {          SOCKET_PROTO_STATE_NADA = 0,          SOCKET_PROTO_STATE_HEADER_COMING, @@ -118,6 +120,8 @@ typedef struct {          int                    windowsize;          char                   lowlat;          char                   nodelay; +        int                    keepalive; +        int                    keepaliveintvl;  } socket_private_t;  | 
