summaryrefslogtreecommitdiffstats
path: root/transport
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-05-18 02:20:17 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-05-21 00:32:27 -0700
commitc0763ba1579fbad705cd29e256fb083376fb0e07 (patch)
tree3f14f1096ca2c59be356967466907360475395b6 /transport
parent608223c792fc308729b522777efad4c6afb8238c (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
Diffstat (limited to 'transport')
-rw-r--r--transport/socket/src/socket.c80
-rw-r--r--transport/socket/src/socket.h4
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;