summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-05-18 01:38:17 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-05-21 00:32:08 -0700
commit174f26f113a7a361a9aa5c959310fcc3867e0dc6 (patch)
tree70d47fedc4285d943e1acee74c4cfc724514e00a
parentc705b679fbe41aa9ac4486ebf46d3b2ae95d1628 (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.c80
-rw-r--r--xlators/protocol/transport/socket/src/socket.h4
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;