From e71b50e49612af4e76510b0c2a6f0519adfd852d Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Mon, 20 Sep 2010 08:09:09 +0000 Subject: rpc-transport/socket: set keepalive socket option. Signed-off-by: Raghavendra G Signed-off-by: Vijay Bellur 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 --- rpc/rpc-transport/socket/src/socket.c | 88 +++++++++++++++++++++++++++++++++++ rpc/rpc-transport/socket/src/socket.h | 3 ++ 2 files changed, 91 insertions(+) diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 17c66d9a374..0f0825be8ae 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 44acc66a0a5..f7471ffb85c 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; -- cgit