static void rpc_clnt_start_ping (void *rpc_ptr) { struct rpc_clnt *rpc = NULL; rpc_clnt_connection_t *conn = NULL; struct timespec timeout = {0, }; int frame_count = 0; int unref = 0; rpc = (struct rpc_clnt*) rpc_ptr; conn = &rpc->conn; if (conn->ping_timeout == 0) { gf_log (THIS->name, GF_LOG_DEBUG, "ping timeout is 0," " returning"); return; } pthread_mutex_lock (&conn->lock); { unref = rpc_clnt_remove_ping_timer_locked (rpc); if (conn->saved_frames) { GF_ASSERT (conn->saved_frames->count >= 0); /* treat the case where conn->saved_frames is NULL as no pending frames */ frame_count = conn->saved_frames->count; } if ((frame_count == 0) || !conn->connected) { gf_log (THIS->name, GF_LOG_DEBUG, "returning as transport is already disconnected" " OR there are no frames (%d || %d)", !conn->connected, frame_count); pthread_mutex_unlock (&conn->lock); if (unref) rpc_clnt_unref (rpc); return; } if (__rpc_clnt_rearm_ping_timer (rpc, rpc_clnt_ping_timer_expired) == -1) { gf_log (THIS->name, GF_LOG_WARNING, "unable to setup ping timer"); pthread_mutex_unlock (&conn->lock); if (unref) rpc_clnt_unref (rpc); return; } } pthread_mutex_unlock (&conn->lock); if (unref) rpc_clnt_unref (rpc); rpc_clnt_ping(rpc); }
int glusterd_conn_init (glusterd_conn_t *conn, char *sockpath, int frame_timeout, glusterd_conn_notify_t notify) { int ret = -1; dict_t *options = NULL; struct rpc_clnt *rpc = NULL; xlator_t *this = THIS; glusterd_svc_t *svc = NULL; if (!this) goto out; svc = glusterd_conn_get_svc_object (conn); if (!svc) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_GET_FAIL, "Failed to get the service"); goto out; } ret = rpc_transport_unix_options_build (&options, sockpath, frame_timeout); if (ret) goto out; ret = dict_set_str (options, "transport.socket.ignore-enoent", "on"); if (ret) goto out; /* @options is free'd by rpc_transport when destroyed */ rpc = rpc_clnt_new (options, this->ctx, (char *)svc->name, 16); if (!rpc) { ret = -1; goto out; } ret = rpc_clnt_register_notify (rpc, glusterd_conn_common_notify, conn); if (ret) goto out; ret = snprintf (conn->sockpath, sizeof (conn->sockpath), "%s", sockpath); if (ret < 0) goto out; else ret = 0; conn->frame_timeout = frame_timeout; conn->rpc = rpc; conn->notify = notify; out: if (ret) { if (rpc) { rpc_clnt_unref (rpc); rpc = NULL; } } return ret; }
int rpc_clnt_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { struct rpc_clnt *rpc = NULL; xlator_t *this = NULL; rpc_clnt_connection_t *conn = NULL; call_frame_t *frame = NULL; struct timespec timeout = {0, }; int unref = 0; if (!myframe) { gf_log (THIS->name, GF_LOG_WARNING, "frame with the request is NULL"); goto out; } frame = myframe; this = frame->this; rpc = frame->local; frame->local = NULL; /* Prevent STACK_DESTROY from segfaulting */ conn = &rpc->conn; pthread_mutex_lock (&conn->lock); { if (req->rpc_status == -1) { unref = rpc_clnt_remove_ping_timer_locked (rpc); if (unref) { gf_log (this->name, GF_LOG_WARNING, "socket or ib related error"); } else { /* timer expired and transport bailed out */ gf_log (this->name, GF_LOG_WARNING, "socket disconnected"); } conn->ping_started = 0; goto unlock; } unref = rpc_clnt_remove_ping_timer_locked (rpc); if (__rpc_clnt_rearm_ping_timer (rpc, rpc_clnt_start_ping) == -1) { gf_log (this->name, GF_LOG_WARNING, "failed to set the ping timer"); } } unlock: pthread_mutex_unlock (&conn->lock); out: if (unref) rpc_clnt_unref (rpc); if (frame) STACK_DESTROY (frame->root); return 0; }
void cleanup_and_exit (int signum) { glusterfs_ctx_t *ctx = NULL; xlator_t *trav = NULL; ctx = glusterfs_ctx_get (); /* TODO: is this the right place? */ if (!ctx) return; if (ctx->cleanup_started) return; ctx->cleanup_started = 1; glusterfs_mgmt_pmap_signout (ctx); /* Call fini() of FUSE xlator first: * so there are no more requests coming and * 'umount' of mount point is done properly */ trav = ctx->master; if (trav && trav->fini) { THIS = trav; trav->fini (trav); } gf_log ("glusterfsd", GF_LOG_NORMAL, "shutting down"); glusterfs_pidfile_cleanup (ctx); exit (0); #if 0 /* TODO: Properly do cleanup_and_exit(), with synchronisations */ if (ctx->mgmt) rpc_clnt_unref (ctx->mgmt); /* call fini() of each xlator */ trav = NULL; if (ctx->active) trav = ctx->active->top; while (trav) { if (trav->fini) { THIS = trav; trav->fini (trav); } trav = trav->next; } #endif }
/* Must be called under conn->lock */ static int __rpc_clnt_rearm_ping_timer (struct rpc_clnt *rpc, gf_timer_cbk_t cbk) { rpc_clnt_connection_t *conn = &rpc->conn; rpc_transport_t *trans = conn->trans; struct timespec timeout = {0, }; gf_timer_t *timer = NULL; if (conn->ping_timer) { gf_log_callingfn ("", GF_LOG_CRITICAL, "%s: ping timer event already scheduled", conn->trans->peerinfo.identifier); return -1; } timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); timer = gf_timer_call_after (rpc->ctx, timeout, cbk, (void *) rpc); if (timer == NULL) { gf_log (trans->name, GF_LOG_WARNING, "unable to setup ping timer"); /* This unref can't be the last. We just took a ref few lines * above. So this can be performed under conn->lock. */ rpc_clnt_unref (rpc); conn->ping_started = 0; return -1; } conn->ping_timer = timer; conn->ping_started = 1; return 0; }
void rpc_clnt_ping_timer_expired (void *rpc_ptr) { struct rpc_clnt *rpc = NULL; rpc_transport_t *trans = NULL; rpc_clnt_connection_t *conn = NULL; int disconnect = 0; int transport_activity = 0; struct timespec timeout = {0, }; struct timeval current = {0, }; rpc = (struct rpc_clnt*) rpc_ptr; conn = &rpc->conn; trans = conn->trans; if (!trans) { gf_log ("ping-timer", GF_LOG_WARNING, "transport not initialized"); goto out; } pthread_mutex_lock (&conn->lock); { if (conn->ping_timer) { gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; rpc_clnt_unref (rpc); } gettimeofday (¤t, NULL); if (((current.tv_sec - conn->last_received.tv_sec) < conn->ping_timeout) || ((current.tv_sec - conn->last_sent.tv_sec) < conn->ping_timeout)) { transport_activity = 1; } if (transport_activity) { gf_log (trans->name, GF_LOG_TRACE, "ping timer expired but transport activity " "detected - not bailing transport"); timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (rpc->ctx, timeout, rpc_clnt_ping_timer_expired, (void *) rpc); if (conn->ping_timer == NULL) { gf_log (trans->name, GF_LOG_WARNING, "unable to setup ping timer"); conn->ping_started = 0; rpc_clnt_unref (rpc); } } else { conn->ping_started = 0; disconnect = 1; } } pthread_mutex_unlock (&conn->lock); if (disconnect) { gf_log (trans->name, GF_LOG_CRITICAL, "server %s has not responded in the last %d " "seconds, disconnecting.", trans->peerinfo.identifier, conn->ping_timeout); rpc_transport_disconnect (conn->trans); } out: return; }
static void rpc_clnt_start_ping (void *rpc_ptr) { struct rpc_clnt *rpc = NULL; rpc_clnt_connection_t *conn = NULL; struct timespec timeout = {0, }; int frame_count = 0; rpc = (struct rpc_clnt*) rpc_ptr; conn = &rpc->conn; if (conn->ping_timeout == 0) { gf_log (THIS->name, GF_LOG_DEBUG, "ping timeout is 0," " returning"); return; } pthread_mutex_lock (&conn->lock); { if (conn->ping_timer) { gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; conn->ping_started = 0; rpc_clnt_unref (rpc); } if (conn->saved_frames) { GF_ASSERT (conn->saved_frames->count >= 0); /* treat the case where conn->saved_frames is NULL as no pending frames */ frame_count = conn->saved_frames->count; } if ((frame_count == 0) || !conn->connected) { gf_log (THIS->name, GF_LOG_DEBUG, "returning as transport is already disconnected" " OR there are no frames (%d || %d)", !conn->connected, frame_count); pthread_mutex_unlock (&conn->lock); return; } timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (rpc->ctx, timeout, rpc_clnt_ping_timer_expired, (void *) rpc); if (conn->ping_timer == NULL) { gf_log (THIS->name, GF_LOG_WARNING, "unable to setup ping timer"); rpc_clnt_unref (rpc); pthread_mutex_unlock (&conn->lock); return; } else { conn->ping_started = 1; } } pthread_mutex_unlock (&conn->lock); rpc_clnt_ping(rpc); }
int rpc_clnt_ping_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { struct rpc_clnt *rpc = NULL; xlator_t *this = NULL; rpc_clnt_connection_t *conn = NULL; call_frame_t *frame = NULL; struct timespec timeout = {0, }; if (!myframe) { gf_log (THIS->name, GF_LOG_WARNING, "frame with the request is NULL"); goto out; } frame = myframe; this = frame->this; rpc = frame->local; frame->local = NULL; /* Prevent STACK_DESTROY from segfaulting */ conn = &rpc->conn; pthread_mutex_lock (&conn->lock); { if (req->rpc_status == -1) { if (conn->ping_timer != NULL) { gf_log (this->name, GF_LOG_WARNING, "socket or ib related error"); gf_timer_call_cancel (rpc->ctx, conn->ping_timer); conn->ping_timer = NULL; rpc_clnt_unref (rpc); } else { /* timer expired and transport bailed out */ gf_log (this->name, GF_LOG_WARNING, "socket disconnected"); } conn->ping_started = 0; goto unlock; } /*This allows other RPCs to be able to start the ping timer * if they come by before the following start ping routine * is executed by the timer thread.*/ conn->ping_started = 0; gf_timer_call_cancel (this->ctx, conn->ping_timer); timeout.tv_sec = conn->ping_timeout; timeout.tv_nsec = 0; rpc_clnt_ref (rpc); conn->ping_timer = gf_timer_call_after (this->ctx, timeout, rpc_clnt_start_ping, (void *)rpc); if (conn->ping_timer == NULL) { gf_log (this->name, GF_LOG_WARNING, "failed to set the ping timer"); rpc_clnt_unref (rpc); } } unlock: pthread_mutex_unlock (&conn->lock); out: if (frame) STACK_DESTROY (frame->root); return 0; }
int glusterd_conn_term (glusterd_conn_t *conn) { rpc_clnt_unref (conn->rpc); return 0; }