summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2010-09-20 08:09:09 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-09-20 08:13:33 -0700
commite71b50e49612af4e76510b0c2a6f0519adfd852d (patch)
treed31b12be9456e2910bafc9d95a35041387855745
parent1473491b576700bb3891abb8adb49e0c31cef8bc (diff)
rpc-transport/socket: set keepalive socket option.
Signed-off-by: Raghavendra G <raghavendra@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 875 (Implement a new protocol to provide proper backward/forward compatibility) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=875
-rw-r--r--rpc/rpc-transport/socket/src/socket.c88
-rw-r--r--rpc/rpc-transport/socket/src/socket.h3
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 17c66d9a3..0f0825be8 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 44acc66a0..f7471ffb8 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;