Пример #1
0
int cm_server_accept(void)
{
	uint32_t event;
	ssize_t rd;
	int ret;
	struct fi_eq_cm_entry *entry;
	void *eqe_buf[EQE_SIZE] = {0};

	rd = fi_eq_sread(srv_eq, &event, &eqe_buf, EQE_SIZE, -1, 0);
	cr_assert(rd == (sizeof(*entry) + strlen(cli_cm_in_data)));
	cr_assert(event == FI_CONNREQ);

	entry = (struct fi_eq_cm_entry *)eqe_buf;
	cr_assert(!memcmp(cli_cm_in_data, entry->data,
			  strlen(cli_cm_in_data)));

	ret = fi_domain(srv_fab, entry->info, &srv_dom, NULL);
	cr_assert(!ret);

	ret = fi_endpoint(srv_dom, entry->info, &srv_ep, NULL);
	cr_assert(!ret, "fi_endpoint");

	fi_freeinfo(entry->info);

	cq_attr.format = FI_CQ_FORMAT_TAGGED;
	cq_attr.size = 1024;
	cq_attr.wait_obj = 0;

	ret = fi_cq_open(srv_dom, &cq_attr, &srv_cq, &srv_cq);
	cr_assert(!ret);

	ret = fi_ep_bind(srv_ep, &srv_eq->fid, 0);
	cr_assert(!ret);

	ret = fi_ep_bind(srv_ep, &srv_cq->fid, FI_SEND | FI_RECV);
	cr_assert(!ret);

	ret = fi_enable(srv_ep);
	cr_assert(!ret);

	ret = fi_accept(srv_ep, srv_cm_in_data, GNIX_CM_DATA_MAX_SIZE+1);
	cr_assert(ret == -FI_EINVAL);

	ret = fi_accept(srv_ep, srv_cm_in_data, strlen(srv_cm_in_data));
	cr_assert(!ret);

	dbg_printf("Server accept complete.\n");

	return 0;
}
Пример #2
0
static int connreq_handler(struct fi_info *info)
{
	struct cma_node *node;
	int ret;

	if (conn_index == connections) {
		ret = -ENOMEM;
		goto err1;
	}

	node = &nodes[conn_index++];
	ret = init_node(node, info);
	if (ret)
		goto err2;

	ret = fi_accept(node->ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err2;
	}

	return 0;

err2:
	connects_left--;
err1:
	printf("cmatose: failing connection request\n");
	fi_reject(pep, info->handle, NULL, 0);
	return ret;
}
Пример #3
0
int ft_server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "listen");
		return (int) rd;
	}

	fi = entry.info;
	if (event != FI_CONNREQ) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		goto err;

	ret = ft_init_ep();
	if (ret)
		goto err;

	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "accept");
		ret = (int) rd;
		goto err;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	return 0;

err:
	fi_reject(pep, fi->handle, NULL, 0);
	return ret;
}
Пример #4
0
static int ft_accept(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	rd = ft_get_event(&event, &entry, sizeof entry,
			  FI_CONNREQ, sizeof entry);
	if (rd < 0)
		return (int) rd;

	fabric_info = entry.info;
	ret = ft_open_active();
	if (ret)
		return ret;

	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		return ret;
	}

	rd = ft_get_event(&event, &entry, sizeof entry,
			  FI_CONNECTED, sizeof entry);
	if (rd < 0)
		return (int) rd;

	return 0;
}
Пример #5
0
/*
 * rpmemd_fip_accept -- accept a single connection request
 *
 * XXX
 *
 * We probably need some timeouts for connection related events.
 */
int
rpmemd_fip_accept(struct rpmemd_fip *fip)
{
	int ret;
	struct fi_eq_cm_entry entry;

	ret = rpmem_fip_read_eq(fip->eq, &entry,
			FI_CONNREQ, &fip->pep->fid, -1);
	if (ret)
		goto err_event_connreq;

	ret = rpmemd_fip_init_cq(fip);
	if (ret)
		goto err_init_cq;

	ret = rpmemd_fip_init_ep(fip, entry.info);
	if (ret)
		goto err_init_ep;

	ret = fip->ops->post(fip);
	if (ret)
		goto err_post;

	ret = fi_accept(fip->ep, NULL, 0);
	if (ret) {
		RPMEMD_FI_ERR(ret, "accepting connection request");
		goto err_accept;
	}

	ret = rpmem_fip_read_eq(fip->eq, &entry,
			FI_CONNECTED, &fip->ep->fid, -1);
	if (ret)
		goto err_event_connected;

	return 0;
err_event_connected:
err_accept:
err_post:
	rpmemd_fip_fini_ep(fip);
err_init_ep:
	rpmemd_fip_fini_cq(fip);
err_init_cq:
err_event_connreq:
	return -1;
}
Пример #6
0
void Connection::on_connect_request(struct fi_eq_cm_entry* event,
                                    struct fid_domain* pd,
                                    struct fid_cq* cq) {
  int err = fi_endpoint(pd, event->info, &ep_, this);
  if (err) {
    L_(fatal) << "fi_endpoint failed: " << err << "=" << fi_strerror(-err);
    throw LibfabricException("fi_endpoint failed");
  }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
  err = fi_ep_bind(ep_, (::fid_t)eq_, 0);
  if (err) {
    L_(fatal) << "fi_ep_bind failed to eq: " << err << "=" << fi_strerror(-err);
    throw LibfabricException("fi_ep_bind failed to eq");
  }
  err = fi_ep_bind(ep_, (fid_t)cq, FI_SEND | FI_RECV | FI_SELECTIVE_COMPLETION);
  if (err) {
    L_(fatal) << "fi_ep_bind failed to cq: " << err << "=" << fi_strerror(-err);
    throw LibfabricException("fi_ep_bind failed to cq");
  }
#pragma GCC diagnostic pop

  // setup(pd);
  setup_mr(pd);

  auto private_data = get_private_data();
  assert(private_data->size() <= 255);

  err = fi_enable(ep_);
  if (err) {
    L_(fatal) << "fi_enable failed: " << err << "=" << fi_strerror(-err);
    throw LibfabricException("fi_enable failed");
  }
  // accept_connect_request();
  err = fi_accept(ep_, private_data->data(), private_data->size());
  if (err) {
    L_(fatal) << "fi_accept failed: " << err << "=" << fi_strerror(-err);
    throw LibfabricException("fi_accept failed");
  }

  // setup(pd);
  setup();
}
Пример #7
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	struct fi_info *info = NULL;
	ssize_t rd;
	int ret;

	/* Wait for connection request from client */
	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		return (int) rd;
	}

	info = entry.info;
	if (event != FI_CONNREQ) {
		FT_ERR("Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = fi_domain(fabric, info, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(info);
	if (ret)
		 goto err;

	ret = ft_init_ep();
	if (ret)
		goto err;

	/* Accept the incoming connection. Also transitions endpoint to active state */
	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	/* Wait for the connection to be established */
	rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		goto err;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		FT_ERR("Unexpected CM event %d fid %p (ep %p)\n", event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	ret = check_address(&ep->fid, "accept");
	if (ret) {
		goto err;
	}

	fi_freeinfo(info);
	return 0;

err:
	fi_reject(pep, info->handle, NULL, 0);
	fi_freeinfo(info);
	return ret;
}
Пример #8
0
static int hook_accept(struct fid_ep *ep, const void *param, size_t paramlen)
{
	struct hook_ep *myep = container_of(ep, struct hook_ep, ep);

	return fi_accept(myep->hep, param, paramlen);
}
Пример #9
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	struct fi_info *info = NULL;
	ssize_t rd;
	int ret;

	/* Wait for connection request from client */
	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, cmeq, "fi_eq_sread", "listen");
		return (int) rd;
	}

	info = entry.info;
	if (event != FI_CONNREQ) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err1;
	}

	ret = fi_domain(fab, info, &dom, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err1;
	}

	ret = alloc_ep_res(info);
	if (ret)
		 goto err1;

	ret = bind_ep_res();
	if (ret)
		goto err3;

	/* Accept the incoming connection. Also transitions endpoint to active state */
	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err3;
	}

	/* Wait for the connection to be established */
	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, cmeq, "fi_eq_sread", "accept");
		ret = (int) rd;
		goto err3;
	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err3;
	}

	fi_freeinfo(info);
	return 0;

err3:
	free_ep_res();
err1:
	fi_reject(pep, info->handle, NULL, 0);
	fi_freeinfo(info);
	return ret;
}
Пример #10
0
static int server_accept(size_t paramlen)
{
	uint32_t event;
	int ret;

	ret = server_listen(paramlen);
	if (ret)
		return ret;

	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err;
	}

	ret = ft_alloc_active_res(fi);
	if (ret) {
		FT_PRINTERR("alloc_active_res", ret);
		goto err;
	}

	ret = ft_init_ep();
	if (ret) {
		FT_PRINTERR("init_ep", ret);
		goto err;
	}
	/* Data will apppear on accept event on remote end. */
	ft_fill_buf(cm_data, paramlen);

	/* Accept the incoming connection. Also transitions endpoint to active
	 * state.
	 */
	ret = fi_accept(ep, cm_data, paramlen);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err;
	}

	/* Local FI_CONNECTED event does not have data associated. */
	memset(entry, 0, sizeof(*entry));
	ret = fi_eq_sread(eq, &event, entry, sizeof(*entry), -1, 0);
	if (ret != sizeof(*entry)) {
		FT_PROCESS_EQ_ERR(ret, eq, "fi_eq_sread", "accept");
		goto err;
	}

	if (event != FI_CONNECTED || entry->fid != &ep->fid) {
		FT_ERR("Unexpected CM event %d fid %p (ep %p)", event,
				entry->fid, ep);
		ret = -FI_EOTHER;
		goto err;
	}

	fi_shutdown(ep, 0);
	ret = read_shutdown_event();
	if (ret)
		goto err;

	FT_CLOSE_FID(ep);
	FT_CLOSE_FID(rxcq);
	FT_CLOSE_FID(txcq);
	FT_CLOSE_FID(rxcntr);
	FT_CLOSE_FID(txcntr);
	FT_CLOSE_FID(av);
	FT_CLOSE_FID(domain);

	return 0;

err:
	fi_reject(pep, fi->handle, NULL, 0);
	return ret;
}
Пример #11
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret, k;
	int num_conn_reqs = 0, num_connected = 0;
	struct ep_info *ep_state_array = NULL;

	ep_array = calloc(ep_cnt, sizeof(*ep_array));
	if (!ep_array)
		return -FI_ENOMEM;

	ep_state_array = calloc(ep_cnt, sizeof(*ep_state_array));
	if (!ep_state_array)
		return -FI_ENOMEM;

	while (num_connected != ep_cnt) {
		rd = fi_eq_sread(eq, &event, &entry, sizeof entry, -1, 0);
		if (rd != sizeof entry) {
			FT_PROCESS_EQ_ERR(rd, eq, "fi_eq_sread", "cm-event");
			ret = (int) rd;
			goto err;
		}

		switch(event) {
		case FI_CONNREQ:
			if (num_conn_reqs == ep_cnt) {
				fprintf(stderr, "Unexpected CM event %d\n", event);
				ret = -FI_EOTHER;
				goto err;
			}
			fi = ep_state_array[num_conn_reqs].fi = entry.info;
			ep_state_array[num_conn_reqs].state = FT_EP_CONNECT_RCVD;

			if (num_conn_reqs == 0) {
				ret = fi_domain(fabric, fi, &domain, NULL);
				if (ret) {
					FT_PRINTERR("fi_domain", ret);
					goto err;
				}

				ret = alloc_ep_res(fi);
				if (ret)
					goto err;
			}

			ret = fi_endpoint(domain, fi, &ep_array[num_conn_reqs], NULL);
			if (ret) {
				FT_PRINTERR("fi_endpoint", ret);
				goto err;
			}

			ep_state_array[num_conn_reqs].ep = ep_array[num_conn_reqs];
			ret = bind_ep_res(ep_array[num_conn_reqs]);
			if (ret)
				goto err;

			ret = fi_accept(ep_array[num_conn_reqs], NULL, 0);
			if (ret) {
				FT_PRINTERR("fi_accept", ret);
				goto err;
			}

			ep_state_array[num_conn_reqs].state = FT_EP_CONNECTING;
			num_conn_reqs++;
			break;

		case FI_CONNECTED:
			if (num_conn_reqs <= num_connected) {
				ret = -FI_EOTHER;
				goto err;
			}

			for (k = 0; k < num_conn_reqs; k++) {
				if (ep_state_array[k].state != FT_EP_CONNECTING)
					continue;
				if (&ep_state_array[k].ep->fid == entry.fid) {
					ep_state_array[k].state = FT_EP_CONNECTED;
					num_connected++;
					if (num_connected != ep_cnt)
						fi_freeinfo(ep_state_array[k].fi);
					break;
				}
			}

			if (k == num_conn_reqs) {
				fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
					event, entry.fid, ep);
				ret = -FI_EOTHER;
				goto err;
			}
			break;

		default:
			ret = -FI_EOTHER;
			goto err;
		}
	}

	/* Post recv */
	if (rx_shared_ctx)
		ret = ft_post_rx(srx_ctx, MAX(rx_size, FT_MAX_CTRL_MSG), &rx_ctx);
	else
		ret = ft_post_rx(ep_array[0], MAX(rx_size, FT_MAX_CTRL_MSG), &rx_ctx);
	if (ret)
		goto err;

	free(ep_state_array);
	return 0;
err:
	for (k = 0; k < ep_cnt; k++) {
		switch(ep_state_array[k].state) {
		case FT_EP_CONNECT_RCVD:
			fi_reject(pep, ep_state_array[k].fi->handle, NULL, 0);
			break;

		case FT_EP_CONNECTING:
		case FT_EP_CONNECTED:
			fi_shutdown(ep_state_array[k].ep, 0);
			break;

		case FT_EP_STATE_INIT:
		default:
			break;
		}
	}

	free(ep_state_array);
	return ret;
}
Пример #12
0
static void test_connect_with_accept_blocking_on_eq_fq_SERVER(void)
{
    int ret;

    printf("SERVER running\n");

    setup_ofi(NULL, NULL, FI_SOURCE);

#if WANT_FDS
    // Add the EQ FD to the epoll fd
    static struct epoll_event edt;
    memset(&edt, 0, sizeof(edt));
    edt.events = EPOLLIN;
    edt.data.u32 = 2222;
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fidev.eq_fd, &edt);
    if (ret < 0) {
        error("server epoll_ctl failed");
    }
#endif

    // Make a PEP
    ret = fi_passive_ep(fidev.fabric, fidev.info, &fidev.pep, NULL);
    if (0 != ret) {
        error("fi_passive_ep failed");
    }

#if WANT_FIXED_PORT
    size_t ss = sizeof(sin);
    ret = fi_getname(&(fidev.pep->fid), &sin, &ss);
    if (0 != ret) {
        error("fi_setname failed");
    }
    sin.sin_port = htons(listen_port);

    // Bind the PEP to listen on a specific port
    ret = fi_setname(&(fidev.pep->fid), &sin, sizeof(sin));
    if (0 != ret) {
        error("fi_setname failed");
    }
#endif

    // Bind the EQ to the PEP
    ret = fi_pep_bind(fidev.pep, &fidev.eq->fid, 0);
    if (0 != ret) {
        error("fi_pep_bind failed");
    }

    // Listen
    ret = fi_listen(fidev.pep);
    if (0 != ret) {
        error("fi_listen failed");
    }

    // Get the actual address of this PEP
    struct sockaddr_in sinout;
    size_t s = sizeof(sinout);
    ret = fi_getname(&(fidev.pep->fid), &sinout, &s);
    if (0 != ret) {
        error("fi_setname failed");
    }
    sin.sin_family = sinout.sin_family;
    sin.sin_addr = sinout.sin_addr;
    sin.sin_port = sinout.sin_port;

    // Print server addr
    printf("SERVER listening on %s\n", addrstr(&sin));

    // Send our node (IP addr) and service (port) to the client
    snprintf(ofi_node, sizeof(ofi_node) - 1, "%s",
             inet_ntoa(sin.sin_addr));
    snprintf(ofi_service, sizeof(ofi_service) - 1, "%d",
             ntohs(sin.sin_port));
    MPI_Send(ofi_node, sizeof(ofi_node) - 1, MPI_CHAR,
             1, 101, MPI_COMM_WORLD);
    MPI_Send(ofi_service, sizeof(ofi_service) - 1, MPI_CHAR,
             1, 102, MPI_COMM_WORLD);
    printf("SERVER sent via MPI to client: %s / %s\n", ofi_node, ofi_service);

#if WANT_FDS
    // Now wait for the listen to complete
    int nevents;
    #define NEVENTS 32
    struct epoll_event events[NEVENTS];
    int timeout = 10000;
    while (1) {
        printf("SERVER blocking on epoll\n");
        nevents = epoll_wait(epoll_fd, events, NEVENTS, timeout);
        if (nevents < 0) {
            if (errno != EINTR) {
                error("server epoll wait failed");
            } else {
                continue;
            }
        } else {
            printf("SERVER successfully woke up from epoll! %d events\n", nevents);
            for (int i = 0; i < nevents; ++i) {
                if (events[i].data.u32 != 2222) {
                    error("server unexpected epoll return type");
                }
            }
            // If we got the expected event, then go read from the EQ
            break;
        }
    }
#endif

    // Wait for the FI_CONNREQ event
    uint32_t event;
    uint8_t *entry_buffer;
    size_t expected_len = sizeof(struct fi_eq_cm_entry) +
        sizeof(client_data);
    entry_buffer = (uint8_t*) calloc(1, expected_len);
    if (NULL == entry_buffer) {
        error("calloc failed");
    }
    struct fi_eq_cm_entry *entry = (struct fi_eq_cm_entry*) entry_buffer;

    while (1) {
        printf("SERVER waiting for FI_CONNREQ\n");
#if WANT_FDS
        ret = fi_eq_read(fidev.eq, &event, entry, expected_len, 0);
#else
        ret = fi_eq_sread(fidev.eq, &event, entry, expected_len, -1, 0);
#endif
        if (-FI_EAVAIL == ret) {
            printf("server fi_eq_sread failed because there's something in the error queue\n");
            char buffer[2048];
            struct fi_eq_err_entry *err_entry = (struct fi_eq_err_entry*) buffer;
            ret = fi_eq_readerr(fidev.eq, err_entry, 0);
            printf("error code: %d (%s), prov err code: %d (%s)\n", err_entry->err, fi_strerror(err_entry->err), err_entry->prov_errno, fi_strerror(err_entry->prov_errno));
            error("sad panda");
        } else if (-EAGAIN == ret) {
            fprintf(stderr, "SERVER fi_eq_sread fail got -EAGAIN... trying again...\n");
            sleep(1);
            continue;
        } else if (ret < 0) {
            fprintf(stderr, "SERVER fi_eq_sread fail: %s (FI_EAVAIL = %d, -ret = %d)\n", fi_strerror(-ret), FI_EAVAIL, -ret);
            error("SERVER fi_eq_sread failed for some random reason");
        } else if (event != FI_CONNREQ) {
            error("SERVER got some unexpected event");
        } else if (ret != expected_len) {
            error("SERVER got wrong length back from fi_eq_sread");
        }

        uint32_t *d = (uint32_t*) entry->data;
        for (int i = 0; i < (sizeof(client_data) / sizeof(uint32_t)); ++i) {
            if (d[i] != client_data[i]) {
                printf("SERVER got wrong CM client data: d[%d]=%d, should be %d\n",
                       i, d[i], client_data[i]);
            }
        }

        printf("SERVER got FI_CONNREQ, correct size, and correct data -- yay!\n");
        break;
    }

    // Silly logistics: setup_ofi_active adds the fd to the epoll set.
    // But we already added it.  So for simplicity, just remove it
    // here so that setup_ofi_active() can re-add it.
#if WANT_FDS
    // Remove the EQ FD from the epoll fd
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fidev.eq_fd, &edt);
    if (ret < 0) {
        error("server epoll_ctl DEL failed");
    }
#endif

    // Make an active endpoint
    setup_ofi_active(entry->info, &ficonn.ep);

    // Accept the incoming connection
    ret = fi_accept(ficonn.ep, (void*) server_data, sizeof(server_data));
    if (ret != 0) {
        printf("fi_accept: ret=%d, %s\n", ret, fi_strerror(-ret));
        error("SERVER fi_accept failed\n");
    }

    // Need to read and get a FI_CONNECTED event
    while (1) {
        printf("SERVER waiting for FI_CONNECTED\n");
#if WANT_FDS
        ret = fi_eq_read(fidev.eq, &event, entry, expected_len, 0);
#else
        ret = fi_eq_sread(fidev.eq, &event, entry, expected_len, -1, 0);
#endif
        if (-FI_EAVAIL == ret) {
            printf("server fi_eq_sread failed because there's something in the error queue\n");
            char buffer[2048];
            struct fi_eq_err_entry *err_entry = (struct fi_eq_err_entry*) buffer;
            ret = fi_eq_readerr(fidev.eq, err_entry, 0);
            printf("error code: %d (%s), prov err code: %d (%s)\n", err_entry->err, fi_strerror(err_entry->err), err_entry->prov_errno, fi_strerror(err_entry->prov_errno));
            error("sad panda");
        } else if (-EAGAIN == ret) {
            fprintf(stderr, "SERVER fi_eq_sread fail got -EAGAIN... trying again...\n");
            sleep(1);
            continue;
        } else if (ret < 0) {
            fprintf(stderr, "SERVER fi_eq_sread fail: %s (FI_EAVAIL = %d, -ret = %d)\n", fi_strerror(-ret), FI_EAVAIL, -ret);
            error("SERVER fi_eq_sread failed for some random reason");
        } else if (event != FI_CONNECTED) {
            error("SERVER got some unexpected event");
        }

        printf("SERVER got FI_CONNECTED -- yay!\n");
        break;
    }

    // Post a recv buffer for the client to send
    int msg[4] = { 0 };
    int len = sizeof(msg);
    printf("SERVER receiving len of %d\n", len);

    struct fid_mr no_mr;
    struct fid_mr *mr;
    void *recv_context = (void*) 0x17;
#if 0
    fi_mr_reg(fidev.domain, msg, len, FI_SEND | FI_RECV,
              0, (uint64_t)(uintptr_t) msg, 0, &mr, NULL);
#else
    // Try using no mr, like fi_msg_pingpong...
    memset(&no_mr, 0, sizeof(no_mr));
    mr = &no_mr;
#endif
    ret = fi_recv(ficonn.ep, msg, len,
                  fi_mr_desc(mr), 0, recv_context);
    if (ret < 0) {
        printf("fi_recv failed! %d, %s\n", ret, fi_strerror(-ret));
        MPI_Abort(MPI_COMM_WORLD, 37);
    }

    sleep(1);
    printf("SERVER posted receive -- waiting for client to send\n");
    MPI_Barrier(MPI_COMM_WORLD);

    // Wait for receive completion
    struct fi_cq_entry cqe;
    while (1) {
        ret = fi_cq_sread(ficonn.cq, &cqe, 1, 0, -1);
        if (cqe.op_context == recv_context) {
            printf("SERVER receive completed\n");
            break;
        } else {
            printf("SERVER got some other completion... continuing\n");
        }
    }

    printf("SERVER finished -- waiting for client before teardown\n");
    MPI_Barrier(MPI_COMM_WORLD);

    printf("SERVER tearing down\n");
    fi_close(&(mr->fid));
    teardown_ofi();
}
Пример #13
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	struct fi_info *info = NULL;
	ssize_t rd;
	int ret;

	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		printf("fi_eq_sread %zd %s\n", rd, fi_strerror((int) -rd));
		return (int) rd;
	}

	if (event != FI_CONNREQ) {
		printf("Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err1;
	}

	info = entry.info;
	ret = fi_domain(fab, info, &dom, NULL);
	if (ret) {
		printf("fi_domain %s\n", fi_strerror(-ret));
		goto err1;
	}

	ret = fi_endpoint(dom, info, &ep, NULL);
	if (ret) {
		printf("fi_endpoint for req %s\n", fi_strerror(-ret));
		goto err1;
	}

	ret = alloc_ep_res(info);
	if (ret)
		 goto err2;

	ret = bind_ep_res();
	if (ret)
		goto err3;

	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		printf("fi_accept %s\n", fi_strerror(-ret));
		goto err3;
	}

	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		printf("fi_eq_sread %zd %s\n", rd, fi_strerror((int) -rd));
		goto err3;
	}

	if (event != FI_COMPLETE || entry.fid != &ep->fid) {
		printf("Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
		ret = -FI_EOTHER;
		goto err3;
	}

	fi_freeinfo(info);
	return 0;

err3:
	free_ep_res();
err2:
	fi_close(&ep->fid);
err1:
	fi_reject(pep, info->connreq, NULL, 0);
	fi_freeinfo(info);
	return ret;
}
Пример #14
0
static int server_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	struct fi_info *info = NULL;
	ssize_t rd;
	int ret;

	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		return (int) rd;
	}

	info = entry.info;
	if (event != FI_CONNREQ) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		ret = -FI_EOTHER;
		goto err1;
	}

	ret = fi_domain(fab, info, &dom, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		goto err1;
	}


	ret = fi_endpoint(dom, info, &ep, NULL);
	if (ret) {
		FT_PRINTERR("fi_endpoint", -ret);
		goto err1;
	}

	ret = alloc_ep_res(info);
	if (ret)
		 goto err1;

	ret = bind_ep_res();
	if (ret)
		goto err3;

	ret = fi_accept(ep, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_accept", ret);
		goto err3;
	}

	rd = fi_eq_sread(cmeq, &event, &entry, sizeof entry, -1, 0);
 	if (rd != sizeof entry) {
		FT_PRINTERR("fi_eq_sread", rd);
		goto err3;
 	}

	if (event != FI_CONNECTED || entry.fid != &ep->fid) {
		fprintf(stderr, "Unexpected CM event %d fid %p (ep %p)\n",
			event, entry.fid, ep);
 		ret = -FI_EOTHER;
 		goto err3;
 	}
 
 	fi_freeinfo(info);
 	return 0;

err3:
	free_ep_res();
err1:
 	fi_reject(pep, info->connreq, NULL, 0);
 	fi_freeinfo(info);
 	return ret;
}
Пример #15
0
static int pp_accept_ctx(struct pingpong_context *ctx)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	int rc = 0;
	ssize_t rd;

	rd = fi_eq_sread(ctx->eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, ctx->eq, "fi_eq_sread", "listen");
		return 1;
	}

	if (event != FI_CONNREQ) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		return 1;
	}

	rc = fi_domain(ctx->fabric, entry.info, &ctx->dom, NULL);
	if (rc) {
		FT_PRINTERR("fi_fdomain", rc);
		return 1;
	}


	rc = fi_mr_reg(ctx->dom, ctx->buf, ctx->size, FI_SEND | FI_RECV, 0, 0, 0, &ctx->mr, NULL);
	if (rc) {
		FT_PRINTERR("fi_mr_reg", rc);
		return 1;
	}

	rc = fi_endpoint(ctx->dom, entry.info, &ctx->ep, NULL);
	if (rc) {
		FT_PRINTERR("fi_endpoint", rc);
		return 1;
	}
	fi_freeinfo(entry.info);

	/* Create event queue */
	if (pp_cq_create(ctx)) {
		fprintf(stderr, "Unable to create event queue\n");
		return 1;
	}

	rc = fi_ep_bind(ctx->ep, &ctx->cq->fid, FI_SEND | FI_RECV);
	if (rc) {
		FT_PRINTERR("fi_ep_bind", rc);
		return 1;
	}

	rc = fi_ep_bind(ctx->ep, &ctx->eq->fid, 0);
	if (rc) {
		FT_PRINTERR("fi_ep_bind", rc);
		return 1;
	}

	rc = fi_enable(ctx->ep);
	if (rc) {
		FT_PRINTERR("fi_enable", rc);
		return EXIT_FAILURE;
	}

	ctx->routs = pp_post_recv(ctx, ctx->rx_depth);
	if (ctx->routs < ctx->rx_depth) {
		FT_ERR("Couldn't post receive (%d)", ctx->routs);
		return 1;
	}

	rc = fi_accept(ctx->ep, NULL, 0);
	if (rc) {
		FT_PRINTERR("fi_accept", rc);
		return 1;
	}

	rd = fi_eq_sread(ctx->eq, &event, &entry, sizeof entry, -1, 0);
	if (rd != sizeof entry) {
		FT_PROCESS_EQ_ERR(rd, ctx->eq, "fi_eq_sread", "accept");
		return 1;
	}

	if (event != FI_CONNECTED) {
		fprintf(stderr, "Unexpected CM event %d\n", event);
		return 1;
	}
	printf("Connection accepted\n");

	return 0;
}