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);
}
示例#2
0
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;
}
示例#4
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;
}
示例#6
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 (&current, 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;
}
示例#7
0
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);
}
示例#8
0
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;
}
示例#9
0
int
glusterd_conn_term (glusterd_conn_t *conn)
{
        rpc_clnt_unref (conn->rpc);
        return 0;
}