Exemple #1
0
/*
 * Connection request attempt failed
 */
void
usdf_cm_msg_connreq_failed(struct usdf_connreq *crp, int error)
{
        struct usdf_pep *pep;
        struct usdf_ep *ep;
        struct usdf_eq *eq;
	fid_t fid;
        struct fi_eq_err_entry err;

        pep = crp->cr_pep;
        ep = crp->cr_ep;
	if (ep != NULL) {
		fid = ep_utofid(ep);
		eq = ep->ep_eq;
		ep->ep_domain->dom_peer_tab[ep->e.msg.ep_rem_peer_id] = NULL;
	} else {
		fid = pep_utofid(pep);
		eq = pep->pep_eq;
	}

        err.fid = fid;
        err.context = NULL;
        err.data = 0;
        err.err = -error;
        err.prov_errno = 0;
        err.err_data = NULL;
        err.err_data_size = 0;
        usdf_eq_write_internal(eq, 0, &err, sizeof(err), USDF_EVENT_FLAG_ERROR);

        usdf_cm_msg_connreq_cleanup(crp);
}
Exemple #2
0
/* Report a connection management related failure. Sometimes there is connection
 * event data that should be copied into the generated event. If the copy_data
 * parameter evaluates to true, then the data will be copied.
 *
 * If data is to be generated for the error entry, then the connection request
 * is assumed to have the data size in host order. If something fails during
 * processing of the error data, then the EQ entry will still be generated
 * without the error data.
 */
void usdf_cm_report_failure(struct usdf_connreq *crp, int error, bool copy_data)
{
	struct fi_eq_err_entry err = {0};
        struct usdf_pep *pep;
        struct usdf_ep *ep;
        struct usdf_eq *eq;
	fid_t fid;
	int ret;

	USDF_DBG_SYS(EP_CTRL, "error=%d (%s)\n", error, fi_strerror(error));

        pep = crp->cr_pep;
        ep = crp->cr_ep;

	if (ep != NULL) {
		fid = ep_utofid(ep);
		eq = ep->ep_eq;
		ep->ep_domain->dom_peer_tab[ep->e.msg.ep_rem_peer_id] = NULL;
	} else {
		fid = pep_utofid(pep);
		eq = pep->pep_eq;
	}

	/* Try to generate the space necessary for the error data. If the
	 * function returns a number greater than or equal to 0, then it was a
	 * success. The return value is the size of the data.
	 */
	if (copy_data) {
		ret = usdf_cm_generate_err_data(eq, crp, &err.err_data);
		if (ret >= 0)
			err.err_data_size = ret;
	}

        err.fid = fid;
        err.err = -error;

        usdf_eq_write_internal(eq, 0, &err, sizeof(err), USDF_EVENT_FLAG_ERROR);

        usdf_cm_msg_connreq_cleanup(crp);
}
Exemple #3
0
static int
usdf_cm_msg_accept_complete(struct usdf_connreq *crp)
{
	struct usdf_ep *ep;
	struct fi_eq_cm_entry entry;
	int ret;

	ep = crp->cr_ep;

	/* post EQ entry */
	entry.fid = ep_utofid(ep);
	entry.info = NULL;
	ret = usdf_eq_write_internal(ep->ep_eq, FI_CONNECTED, &entry,
			sizeof(entry), 0);
	if (ret != sizeof(entry)) {
		usdf_cm_msg_connreq_failed(crp, ret);
		return 0;
	}

	usdf_cm_msg_connreq_cleanup(crp);

	return 0;
}
Exemple #4
0
/*
 * read connection request response from the listener
 */
static int
usdf_cm_msg_connect_cb_rd(void *v)
{
	struct usdf_connreq *crp;
	struct usdf_ep *ep;
	struct usdf_fabric *fp;
	struct usdf_domain *udp;
	struct usdf_connreq_msg *reqp;
	struct fi_eq_cm_entry *entry;
	size_t entry_len;
	int ret;

	crp = v;
	ep = crp->cr_ep;
	fp = ep->ep_domain->dom_fabric;

	ret = read(crp->cr_sockfd, crp->cr_ptr, crp->cr_resid);
	if (ret == -1) {
		usdf_cm_msg_connreq_failed(crp, -errno);
		return 0;
	}

	crp->cr_resid -= ret;
	reqp = (struct usdf_connreq_msg *)crp->cr_data;
	if (crp->cr_resid == 0 && crp->cr_ptr == crp->cr_data + sizeof(*reqp)) {
		reqp->creq_datalen = ntohl(reqp->creq_datalen);
		crp->cr_resid = reqp->creq_datalen;
	}

	/* if resid is 0 now, completely done */
	if (crp->cr_resid == 0) {
		ret = epoll_ctl(fp->fab_epollfd, EPOLL_CTL_DEL,
				crp->cr_sockfd, NULL);
		close(crp->cr_sockfd);
		crp->cr_sockfd = -1;

		entry_len = sizeof(*entry) + reqp->creq_datalen;
		entry = malloc(entry_len);
		if (entry == NULL) {
			usdf_cm_msg_connreq_failed(crp, -errno);
			return 0;
		}
		
		udp = ep->ep_domain;
		ep->e.msg.ep_lcl_peer_id = ntohs(reqp->creq_peer_id);
		ret = usd_create_dest_with_mac(udp->dom_dev, reqp->creq_ipaddr,
				reqp->creq_port, reqp->creq_mac,
				&ep->e.msg.ep_dest);
		if (ret != 0) {
			free(entry);
			usdf_cm_msg_connreq_failed(crp, ret);
			return 0;
		}

		entry->fid = ep_utofid(ep);
		entry->info = NULL;
		memcpy(entry->data, reqp->creq_data, reqp->creq_datalen);
		ret = usdf_eq_write_internal(ep->ep_eq, FI_CONNECTED, entry,
				entry_len, 0);
		free(entry);
		if (ret != entry_len) {
			free(ep->e.msg.ep_dest);
			ep->e.msg.ep_dest = NULL;
			usdf_cm_msg_connreq_failed(crp, ret);
			return 0;
		}

		usdf_cm_msg_connreq_cleanup(crp);
	}
	return 0;
}
static int
usdf_pep_read_connreq(void *v)
{
    struct usdf_connreq *crp;
    struct usdf_pep *pep;
    struct usdf_connreq_msg *reqp;
    struct fi_eq_cm_entry *entry;
    size_t entry_len;
    int ret;
    int n;

    crp = v;
    pep = crp->cr_pep;

    n = read(crp->cr_sockfd, crp->cr_ptr, crp->cr_resid);
    if (n == -1) {
        usdf_cm_msg_connreq_failed(crp, -errno);
        return 0;
    }

    crp->cr_ptr += n;
    crp->cr_resid -= n;

    reqp = (struct usdf_connreq_msg *)crp->cr_data;

    if (crp->cr_resid == 0 && crp->cr_ptr == crp->cr_data + sizeof(*reqp)) {
        reqp->creq_datalen = ntohl(reqp->creq_datalen);
        crp->cr_resid = reqp->creq_datalen;
    }

    /* if resid is 0 now, completely done */
    if (crp->cr_resid == 0) {
        ret = usdf_pep_creq_epoll_del(crp);
        if (ret != 0) {
            usdf_cm_msg_connreq_failed(crp, ret);
            return 0;
        }

        /* create CONNREQ EQ entry */
        entry_len = sizeof(*entry) + reqp->creq_datalen;
        entry = malloc(entry_len);
        if (entry == NULL) {
            usdf_cm_msg_connreq_failed(crp, -errno);
            return 0;
        }

        entry->fid = &pep->pep_fid.fid;
        entry->info = usdf_pep_conn_info(crp);
        if (entry->info == NULL) {
            free(entry);
            usdf_cm_msg_connreq_failed(crp, -FI_ENOMEM);
            return 0;
        }
        memcpy(entry->data, reqp->creq_data, reqp->creq_datalen);
        ret = usdf_eq_write_internal(pep->pep_eq, FI_CONNREQ, entry,
                                     entry_len, 0);
        free(entry);
        if (ret != (int)entry_len) {
            usdf_cm_msg_connreq_failed(crp, ret);
            return 0;
        }
    }

    return 0;
}
Exemple #6
0
/*
 * read connection request response from the listener
 */
static int
usdf_cm_msg_connect_cb_rd(void *v)
{
	struct usdf_connreq *crp;
	struct usdf_ep *ep;
	struct usdf_fabric *fp;
	struct usdf_domain *udp;
	struct usdf_connreq_msg *reqp;
	struct fi_eq_cm_entry *entry;
	size_t entry_len;
	int ret;

	crp = v;
	ep = crp->cr_ep;
	fp = ep->ep_domain->dom_fabric;

	ret = read(crp->cr_sockfd, crp->cr_ptr, crp->cr_resid);
	if (ret == -1)
		goto report_failure_skip_data;

	crp->cr_ptr += ret;
	crp->cr_resid -= ret;

	reqp = (struct usdf_connreq_msg *)crp->cr_data;
	if (crp->cr_resid == 0 && crp->cr_ptr == crp->cr_data + sizeof(*reqp)) {
		reqp->creq_datalen = ntohl(reqp->creq_datalen);
		crp->cr_resid = reqp->creq_datalen;
	}

	/* if resid is 0 now, completely done */
	if (crp->cr_resid == 0) {
		reqp->creq_result = ntohl(reqp->creq_result);

		ret = epoll_ctl(fp->fab_epollfd, EPOLL_CTL_DEL,
				crp->cr_sockfd, NULL);
		close(crp->cr_sockfd);
		crp->cr_sockfd = -1;

		if (reqp->creq_result != FI_SUCCESS) {
			/* Copy the data since this was an explicit rejection.
			 */
			usdf_cm_report_failure(crp, reqp->creq_result, true);
			return 0;
		}

		entry_len = sizeof(*entry) + reqp->creq_datalen;
		entry = malloc(entry_len);
		if (entry == NULL)
			goto report_failure_skip_data;

		udp = ep->ep_domain;
		ep->e.msg.ep_lcl_peer_id = ntohs(reqp->creq_peer_id);
		ret = usd_create_dest(udp->dom_dev, reqp->creq_ipaddr,
				reqp->creq_port, &ep->e.msg.ep_dest);
		if (ret != 0)
			goto free_entry_and_report_failure;

		ep->e.msg.ep_dest->ds_dest.ds_udp.u_hdr.uh_ip.frag_off |=
			htons(IP_DF);

		entry->fid = ep_utofid(ep);
		entry->info = NULL;
		memcpy(entry->data, reqp->creq_data, reqp->creq_datalen);
		ret = usdf_eq_write_internal(ep->ep_eq, FI_CONNECTED, entry,
				entry_len, 0);
		if (ret != (int)entry_len) {
			free(ep->e.msg.ep_dest);
			ep->e.msg.ep_dest = NULL;

			goto free_entry_and_report_failure;
		}

		free(entry);
		usdf_cm_msg_connreq_cleanup(crp);
	}
	return 0;

free_entry_and_report_failure:
	free(entry);
report_failure_skip_data:
	usdf_cm_report_failure(crp, ret, false);
	return 0;
}