diff options
author | Shehjar Tikoo <shehjart@gluster.com> | 2010-05-18 01:38:17 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-05-21 00:32:08 -0700 |
commit | 174f26f113a7a361a9aa5c959310fcc3867e0dc6 (patch) | |
tree | 70d47fedc4285d943e1acee74c4cfc724514e00a | |
parent | c705b679fbe41aa9ac4486ebf46d3b2ae95d1628 (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-- | xlators/protocol/transport/socket/src/socket.c | 80 | ||||
-rw-r--r-- | xlators/protocol/transport/socket/src/socket.h | 4 |
2 files changed, 84 insertions, 0 deletions
diff --git a/xlators/protocol/transport/socket/src/socket.c b/xlators/protocol/transport/socket/src/socket.c index 7f7f8093a7d..9ce5059e840 100644 --- a/xlators/protocol/transport/socket/src/socket.c +++ b/xlators/protocol/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) { @@ -893,6 +925,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 = GF_CALLOC (1, sizeof (*new_trans), gf_common_mt_transport_t); new_trans->xl = this->xl; @@ -1070,6 +1111,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; @@ -1372,6 +1422,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, @@ -1453,6 +1504,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; @@ -1547,6 +1621,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/xlators/protocol/transport/socket/src/socket.h b/xlators/protocol/transport/socket/src/socket.h index bc6d3b27c3a..e02801a5b1c 100644 --- a/xlators/protocol/transport/socket/src/socket.h +++ b/xlators/protocol/transport/socket/src/socket.h @@ -53,6 +53,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, @@ -119,6 +121,8 @@ typedef struct { int windowsize; char lowlat; char nodelay; + int keepalive; + int keepaliveintvl; } socket_private_t; |