Пример #1
0
int PINT_serv_decode_resp(PVFS_fs_id fs_id,
                          void *encoded_resp_p,
                          struct PINT_decoded_msg *decoded_resp_p,
                          PVFS_BMI_addr_t *svr_addr_p,
                          int actual_resp_sz,
                          struct PVFS_server_resp **resp_out_pp)
{
    int ret = -1, server_type = 0;
    const char *server_string;

    ret = PINT_decode(encoded_resp_p, PINT_DECODE_RESP,
                      decoded_resp_p, /* holds data on decoded resp */
                      *svr_addr_p, actual_resp_sz);
    if (ret > -1)
    {
        *resp_out_pp = (struct PVFS_server_resp *)decoded_resp_p->buffer;
        if ((*resp_out_pp)->op == PVFS_SERV_PROTO_ERROR)
        {

            gossip_err("Error: server does not seem to understand "
                       "the protocol that this client is using.\n");
            gossip_err("   Please check server logs for more "
                       "information.\n");

            if (fs_id != PVFS_FS_ID_NULL)
            {
                server_string = PINT_cached_config_map_addr(
                    fs_id, *svr_addr_p, &server_type);
                gossip_err("   Server: %s.\n", server_string);
            }
            else
            {
                gossip_err("   Server: unknown; probably an error "
                           "contacting server listed in pvfs2tab "
                           "file.\n");
            }
            return(-EPROTONOSUPPORT);
        }
    }
    return ret;
}
Пример #2
0
/*
  given mount information, retrieve the server's configuration by
  issuing a getconfig operation.  on successful response, we parse the
  configuration and fill in the config object specified.

  returns 0 on success, -errno on error
*/
int PVFS_mgmt_get_config(
    const PVFS_fs_id * fsid,
    PVFS_BMI_addr_t * addr,
    char *fs_buf,
    int fs_buf_size)
{
    int ret = -PVFS_EINVAL;
    PINT_smcb *smcb = NULL;
    PINT_client_sm *sm_p = NULL;
    PVFS_error error = 0;
    PVFS_credentials creds;
    struct filesystem_configuration_s *cur_fs = NULL;
    PVFS_sys_op_id op_id;
    struct server_configuration_s *config = NULL;
    struct PVFS_sys_mntent mntent;
    int server_type = 0;

    gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_mgmt_get_config entered\n");

    PVFS_util_gen_credentials(&creds);

    PINT_smcb_alloc(&smcb, PVFS_SERVER_GET_CONFIG,
                    sizeof(struct PINT_client_sm),
                    client_op_state_get_machine,
                    client_state_machine_terminate,
                    pint_client_sm_context);
    if(smcb == NULL)
    {
        return -PVFS_ENOMEM;
    }

    sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);

    sm_p->u.get_config.persist_config_buffers = 1;

    PINT_init_msgarray_params(sm_p, *fsid);

    PINT_init_sysint_credentials(sm_p->cred_p, &creds);

    config = PINT_get_server_config_struct(*fsid);

    mntent.the_pvfs_config_server =
        (char*)PINT_cached_config_map_addr(*fsid, *addr, &server_type);

    PINT_put_server_config_struct(config);

    cur_fs = PINT_config_find_fs_id(config, *fsid);

    mntent.encoding = cur_fs->encoding;
    mntent.flowproto = cur_fs->flowproto;

    mntent.fs_id = *fsid;

    mntent.pvfs_fs_name = cur_fs->file_system_name;
    sm_p->u.get_config.config = config;

    sm_p->msgarray_op.msgpair.enc_type = cur_fs->encoding;

    sm_p->u.get_config.mntent = &mntent;

    PINT_msgpair_init(&sm_p->msgarray_op);

    ret = PINT_client_state_machine_post(
        smcb, &op_id, NULL);

    if (ret)
    {
        PVFS_perror_gossip("PINT_client_state_machine_post call", ret);
        error = ret;
    }
    else
    {
        ret = PVFS_mgmt_wait(op_id, "X-get_config", &error);
        if (ret)
        {
            PVFS_perror_gossip("PVFS_mgmt_wait call", ret);
            error = ret;
        }
    }

    if (error)
    {
        goto exit_path;
    }

    gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_mgmt_get_config completed\n");

    /* make sure strings will be null terminated after strncpy */
    fs_buf[fs_buf_size-1] = '\0';

    /* The following copies the retrieved configuration buffers
       into the return buffers */
    strncpy(fs_buf, sm_p->u.get_config.fs_config_buf, (fs_buf_size - 1));

  exit_path:

    if (sm_p && sm_p->u.get_config.persist_config_buffers)
    {
        free(sm_p->u.get_config.fs_config_buf);
        sm_p->u.get_config.fs_config_buf = NULL;
    }

    PINT_mgmt_release(op_id);
    return error;
}
Пример #3
0
static PINT_sm_action msgpairarray_completion_fn(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    PINT_sm_msgarray_op *mop = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
    int ret = -PVFS_EINVAL, i = 0;
    int need_retry = 0;
    struct PINT_decoded_msg decoded_resp;
    const char* server_string = NULL;
    int server_type;

    /* response structure (decoded) */
    struct PVFS_server_resp *resp_p = NULL;

    js_p->error_code = 0;

    gossip_debug(GOSSIP_MSGPAIR_DEBUG, "(%p) msgpairarray state: "
                 "completion_fn\n", smcb);

    for (i = 0; i < mop->count; i++)
    {
        PINT_sm_msgpair_state *msg_p = &mop->msgarray[i];
        assert(msg_p);

	/*
	 * Can take multiple trips through this function as we retry
	 * ones that failed.
	 */
	if (msg_p->complete)
	    continue;

        if (msg_p->op_status != 0)
        {
            char s[1024];
            PVFS_strerror_r(msg_p->op_status, s, sizeof(s));
            server_string = PINT_cached_config_map_addr(
                msg_p->fs_id, msg_p->svr_addr, &server_type);
            if(!server_string)
            {
                server_string = BMI_addr_rev_lookup(msg_p->svr_addr);
            }

            gossip_err("Warning: msgpair failed to %s, will retry: %s\n", server_string, s);
                       
            ++need_retry;
            continue;
        }

        ret = PINT_serv_decode_resp(msg_p->fs_id,
                                    msg_p->encoded_resp_p,
                                    &decoded_resp,
                                    &msg_p->svr_addr,
                                    msg_p->recv_status.actual_size,
                                    &resp_p);
        if (ret != 0)
        {
            PVFS_perror_gossip("msgpairarray decode error", ret);
            msg_p->op_status = ret;
        }
        else
        {
            /* if we've made it this far, the server response status is
             * meaningful, so we save it.
             */
            msg_p->op_status = resp_p->status;
        }

        /* NOTE: we call the function associated with each message,
         *       not just the one from the first array element.  so
         *       there could in theory be different functions for each
         *       message (to handle different types of messages all in
         *       the same array).
         */
        if (msg_p->comp_fn != NULL)
        {
            /* If we call the completion function, store the result on
             * a per message pair basis.  Also store some non-zero
             * (failure) value in js_p->error_code if we see one.
             */
            msg_p->op_status = msg_p->comp_fn(smcb, resp_p, i);
            if (msg_p->op_status != 0)
            {
                js_p->error_code = msg_p->op_status;
            }

            /* even if we see a failure, continue to process with the
             * completion function. -- RobR
             */
        }
        else if (resp_p->status != 0)
        {
            /* no comp_fn specified and status non-zero */
            gossip_debug(GOSSIP_MSGPAIR_DEBUG,
                         "notice: msgpairarray_complete: error %d "
                         "from server %d\n", resp_p->status, i);

            /* save a non-zero status to return if we see one */
            js_p->error_code = resp_p->status;

            /* If we don't have a completion function, there is no point
             * in continuing to process after seeing a failure.
             */
            if (js_p->error_code)
            {
                break;
            }
        }

        /* free all the resources that we used to send and receive. */
        ret = PINT_serv_free_msgpair_resources(
            &msg_p->encoded_req, msg_p->encoded_resp_p, &decoded_resp,
            &msg_p->svr_addr, msg_p->max_resp_sz);
        if (ret)
        {
            PVFS_perror_gossip("Failed to free msgpair resources", ret);
            js_p->error_code = ret;
            return SM_ACTION_COMPLETE;
        }

        msg_p->encoded_resp_p = NULL;
        msg_p->max_resp_sz = 0;

        /*
          mark that this msgpair has been completed and should not be
          retried in the case of possible future retries
        */
        msg_p->complete = 1;

        gossip_debug(GOSSIP_MSGPAIR_DEBUG, "%s: sm %p msgpair %d "
                     "marked complete\n", __func__, smcb, i);
    }

    if (need_retry) {
        /*
         * We only retry msgpairs that are not yet complete.  Factor
         * of two since they are pairs.  If over the count, do not
         * retry, just return one of the error codes.
         */
        mop->params.comp_ct = 0;
        js_p->error_code = 0;
        for (i=0; i < mop->count; i++) {

            PINT_sm_msgpair_state *msg_p = &mop->msgarray[i];

            if (msg_p->complete)
                continue;

            if (msg_p->retry_flag == PVFS_MSGPAIR_RETRY
             && PVFS_ERROR_CLASS(-msg_p->op_status) == PVFS_ERROR_BMI
             && msg_p->retry_count < mop->params.retry_limit) {

                ++msg_p->retry_count;
                mop->params.comp_ct += 2;
                gossip_debug(GOSSIP_MSGPAIR_DEBUG,
                  "*** %s: msgpair %d failed, retry %d\n",
                  __func__, i, msg_p->retry_count);
                if(msg_p->op_status == -BMI_ECANCEL)
                {
                    /* if the error code indicates cancel, then skip the
                     * delay.  We have probably already been waiting a while
                     */
                    gossip_debug(GOSSIP_MSGPAIR_DEBUG,
                       "*** %s: msgpair skipping retry delay.\n", __func__);
                    js_p->error_code = MSGPAIRS_RETRY_NODELAY;
                }
                else
                {
                    gossip_debug(GOSSIP_MSGPAIR_DEBUG,
                       "*** %s: msgpair retrying after delay.\n", __func__);
                    js_p->error_code = MSGPAIRS_RETRY;
                }

            } else {
                char s[1024];
                server_string = PINT_cached_config_map_addr(
                    msg_p->fs_id, msg_p->svr_addr, &server_type);
                if(!server_string)
                {
                    server_string = "[UNKNOWN]";
                }
                PVFS_strerror_r(msg_p->op_status, s, sizeof(s));
                gossip_err_unless_quiet("*** %s: msgpair to server %s failed: %s\n",
                        __func__, server_string, s);
                if(msg_p->retry_flag != PVFS_MSGPAIR_RETRY)
                {
                    gossip_err_unless_quiet("*** No retries requested.\n");
                }
                else if(PVFS_ERROR_CLASS(-msg_p->op_status) !=
                    PVFS_ERROR_BMI)
                {
                    gossip_err_unless_quiet("*** Non-BMI failure.\n");
                }
                else
                {
                    gossip_err_unless_quiet("*** Out of retries.\n");
                }
                if (js_p->error_code == 0)
                    js_p->error_code = msg_p->op_status;
            }

        }
    }
    return SM_ACTION_COMPLETE;
}