diff options
Diffstat (limited to 'xlators/protocol/server/src/server.c')
-rw-r--r-- | xlators/protocol/server/src/server.c | 96 |
1 files changed, 82 insertions, 14 deletions
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index b0697bb7b9d..b45b77baae0 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -36,6 +36,26 @@ #include "authenticate.h" #include "rpcsvc.h" +void +grace_time_handler (void *data) +{ + server_connection_t *conn = NULL; + xlator_t *this = NULL; + + conn = data; + this = conn->this; + + GF_VALIDATE_OR_GOTO (THIS->name, conn, out); + GF_VALIDATE_OR_GOTO (THIS->name, this, out); + + gf_log (this->name, GF_LOG_INFO, "grace timer expired"); + + server_cancel_conn_timer (this, conn); + server_connection_put (this, conn); +out: + return; +} + struct iobuf * gfs_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg, xdrproc_t xdrproc) @@ -554,11 +574,10 @@ int server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, void *data) { - xlator_t *this = NULL; - rpc_transport_t *xprt = NULL; - server_connection_t *conn = NULL; - server_conf_t *conf = NULL; - + xlator_t *this = NULL; + rpc_transport_t *xprt = NULL; + server_connection_t *conn = NULL; + server_conf_t *conf = NULL; if (!xl || !data) { gf_log_callingfn ("server", GF_LOG_WARNING, @@ -589,20 +608,37 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, } case RPCSVC_EVENT_DISCONNECT: conn = get_server_conn_state (this, xprt); - if (conn) - server_connection_cleanup (this, conn); - - gf_log (this->name, GF_LOG_INFO, - "disconnected connection from %s", - xprt->peerinfo.identifier); + if (!conn) + break; + put_server_conn_state (this, xprt); + gf_log (this->name, GF_LOG_INFO, "disconnecting connection" + "from %s", xprt->peerinfo.identifier); list_del (&xprt->list); + pthread_mutex_lock (&conn->lock); + { + if (conn->timer) + goto unlock; + + gf_log (this->name, GF_LOG_INFO, "starting a grace " + "timer for %s", xprt->name); + + conn->timer = gf_timer_call_after (this->ctx, + conf->grace_tv, + grace_time_handler, + conn); + } + unlock: + pthread_mutex_unlock (&conn->lock); + break; case RPCSVC_EVENT_TRANSPORT_DESTROY: - conn = get_server_conn_state (this, xprt); - if (conn) - server_connection_put (this, conn); + /*- conn obj has been disassociated from xprt on first + * disconnect. + * conn cleanup and destruction is handed over to + * grace_time_handler or the subsequent handler that 'owns' + * the conn. Nothing left to be done here. */ break; default: break; @@ -668,6 +704,30 @@ _copy_auth_opt (dict_t *unused, int +server_init_grace_timer (xlator_t *this, dict_t *options, + server_conf_t *conf) +{ + int32_t ret = -1; + int32_t grace_timeout = -1; + + GF_VALIDATE_OR_GOTO ("server", this, out); + GF_VALIDATE_OR_GOTO (this->name, options, out); + GF_VALIDATE_OR_GOTO (this->name, conf, out); + + ret = dict_get_int32 (options, "grace-timeout", &grace_timeout); + if (!ret) + conf->grace_tv.tv_sec = grace_timeout; + else + conf->grace_tv.tv_sec = 10; + + conf->grace_tv.tv_usec = 0; + + ret = 0; +out: + return ret; +} + +int reconfigure (xlator_t *this, dict_t *options) { @@ -761,6 +821,7 @@ reconfigure (xlator_t *this, dict_t *options) "Reconfigure not found for transport" ); } } + ret = server_init_grace_timer (this, options, conf); out: gf_log ("", GF_LOG_DEBUG, "returning %d", ret); @@ -797,6 +858,10 @@ init (xlator_t *this) INIT_LIST_HEAD (&conf->xprt_list); pthread_mutex_init (&conf->mutex, NULL); + ret = server_init_grace_timer (this, this->options, conf); + if (ret) + goto out; + ret = server_build_config (this, conf); if (ret) goto out; @@ -1032,5 +1097,8 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_PATH, .default_value = "/tmp" }, + {.key = {"grace-timeout"}, + .type = GF_OPTION_TYPE_INT, + }, { .key = {NULL} }, }; |