Beispiel #1
0
int ft_init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	if (hints->caps & FI_RMA) {
		ret = ft_set_rma_caps(fi, opts.rma_op);
		if (ret)
			return ret;
	}

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	ret = ft_init_av();
	if (ret)
		return ret;

	return 0;
}
Beispiel #2
0
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	return 0;
}
Beispiel #3
0
static int init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	// set FI_MULTI_RECV flag for all recv operations
	fi->rx_attr->op_flags = FI_MULTI_RECV;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	ret = fi_setopt(&ep->fid, FI_OPT_ENDPOINT, FI_OPT_MIN_MULTI_RECV,
			&tx_size, sizeof(tx_size));
	if (ret)
		return ret;

	ret = post_multi_recv_buffer();
	return ret;
}
Beispiel #4
0
static int client_setup(void)
{
	size_t opt_size;
	int ret;

	/* Get fabric info */
	ret = fi_getinfo(FT_FIVERSION, opts.dst_addr, opts.dst_port, 0, hints,
			&fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	/* Get the maximum cm_size for this domain + endpoint combination */
	opt_size = sizeof(opt_size);
	return fi_getopt(&ep->fid, FI_OPT_ENDPOINT, FI_OPT_CM_DATA_SIZE,
		&cm_data_size, &opt_size);
}
Beispiel #5
0
static int init_fabric(void)
{
	char *node, *service;
	uint64_t flags = 0;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	/* Get fabric info */
	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	/* Get remote address of the server */
	if (opts.dst_addr) {
		addrlen = fi->dest_addrlen;
		remote_addr = malloc(addrlen);
		memcpy(remote_addr, fi->dest_addr, addrlen);
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	/* Open domain */
	ret = fi_domain(fabric, fi, &domain, NULL);
	if (ret) {
		FT_PRINTERR("fi_domain", ret);
		return ret;
	}

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep(NULL);
	if (ret)
		return ret;

	if (opts.dst_addr) {
		/* Insert address to the AV and get the fabric address back */
		ret = fi_av_insert(av, remote_addr, 1, &remote_fi_addr, 0,
				&fi_ctx_av);
		if (ret != 1) {
			FT_PRINTERR("fi_av_insert", ret);
			return ret;
		}
	}

	return 0;
}
Beispiel #6
0
static int client_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	ret = ft_getsrcaddr(opts.src_addr, opts.src_port, hints);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, opts.dst_addr, opts.dst_port, 0, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

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

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep(buf);
	if (ret)
		return ret;

	ret = fi_connect(ep, fi->dest_addr, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_connect", ret);
		return 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", "connect");
		return (int) rd;
	}

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

	return 0;
}
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	/* Check the number of EPs supported by the provider */
	if (ep_cnt > fi->domain_attr->ep_cnt) {
		ep_cnt = fi->domain_attr->ep_cnt;
		fprintf(stderr, "Provider can support only %d of EPs\n", ep_cnt);
	}

	/* Get remote address */
	if (opts.dst_addr) {
		addrlen = fi->dest_addrlen;
		remote_addr = malloc(addrlen * ep_cnt);
		memcpy(remote_addr, fi->dest_addr, addrlen);
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

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

	fi->ep_attr->tx_ctx_cnt = FI_SHARED_CONTEXT;
	fi->ep_attr->rx_ctx_cnt = FI_SHARED_CONTEXT;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = bind_ep_res();
	if (ret)
		return ret;

	return 0;
}
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	/* check max msg size */
	max_inject_size = fi->tx_attr->inject_size;
	if ((opts.options & FT_OPT_SIZE) &&
	    (opts.transfer_size > max_inject_size)) {
		fprintf(stderr, "Msg size greater than max inject size\n");
		return -FI_EINVAL;
	}

	/* Get remote address */
	if (opts.dst_addr) {
		addrlen = fi->dest_addrlen;
		remote_addr = malloc(addrlen);
		memcpy(remote_addr, fi->dest_addr, addrlen);
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

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

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep(NULL);
	if (ret)
		return ret;

	return 0;
}
Beispiel #9
0
int main(int argc, char **argv)
{
	int op, ret;
	int failed = 0;

	hints = fi_allocinfo();
	if (!hints)
		return EXIT_FAILURE;

	while ((op = getopt(argc, argv, FAB_OPTS "h")) != -1) {
		switch (op) {
		default:
			ft_parseinfo(op, optarg, hints, &opts);
			break;
		case '?':
		case 'h':
			usage();
			return EXIT_FAILURE;
		}
	}

	hints->mode = ~0;
	hints->domain_attr->mode = ~0;
	hints->domain_attr->mr_mode = ~(FI_MR_BASIC | FI_MR_SCALABLE);

	ret = fi_getinfo(FT_FIVERSION, NULL, 0, 0, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		goto out;
	}

	if (!fi->domain_attr->cntr_cnt)
		goto out;

	ret = ft_open_fabric_res();
	if (ret)
		goto out;

	printf("Testing CNTRS on fabric %s\n", fi->fabric_attr->name);

	failed = run_tests(test_array, err_buf);
	if (failed > 0)
		printf("Summary: %d tests failed\n", failed);
	else
		printf("Summary: all tests passed\n");

out:
	ft_free_res();
	return ret ? ft_exit_code(ret) : (failed > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}
Beispiel #10
0
int main(int argc, char **argv)
{
	int op, ret;
	int failed;

	hints = fi_allocinfo();
	if (!hints)
		return EXIT_FAILURE;

	while ((op = getopt(argc, argv, FAB_OPTS "h")) != -1) {
		switch (op) {
		default:
			ft_parseinfo(op, optarg, hints);
			break;
		case '?':
		case 'h':
			usage();
			return EXIT_FAILURE;
		}
	}

	hints->mode = ~0;

	ret = fi_getinfo(FT_FIVERSION, NULL, 0, 0, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		goto err;
	}

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

	printf("Testing CQs on fabric %s\n", fi->fabric_attr->name);

	failed = run_tests(test_array, err_buf);
	if (failed > 0) {
		printf("Summary: %d tests failed\n", failed);
	} else {
		printf("Summary: all tests passed\n");
	}

err:
	ft_free_res();
	return ret ? -ret : (failed > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}
Beispiel #11
0
int ft_client_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = ft_alloc_active_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep();
	if (ret)
		return ret;

	ret = fi_connect(ep, fi->dest_addr, NULL, 0);
	if (ret) {
		FT_PRINTERR("fi_connect", ret);
		return 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", "connect");
		ret = (int) rd;
		return ret;
	}

	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;
		return ret;
	}

	return 0;
}
Beispiel #12
0
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	/* Check the optimal number of TX and RX contexts supported by the provider */
	ctx_cnt = MIN(ctx_cnt, fi->domain_attr->tx_ctx_cnt);
	ctx_cnt = MIN(ctx_cnt, fi->domain_attr->rx_ctx_cnt);
	if (!ctx_cnt) {
		fprintf(stderr, "Provider doesn't support contexts\n");
		return 1;
	}

	fi->ep_attr->tx_ctx_cnt = ctx_cnt;
	fi->ep_attr->rx_ctx_cnt = ctx_cnt;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = fi_scalable_ep(domain, fi, &sep, NULL);
	if (ret) {
		FT_PRINTERR("fi_scalable_ep", ret);
		return ret;
	}

	ret = alloc_ep_res(sep);
	if (ret)
		return ret;

	ret = bind_ep_res();
	return ret;
}
Beispiel #13
0
static int init_fabric(void)
{
	uint64_t flags = 0;
	char *node, *service;
	int ret;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		return ret;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		return ret;
	}

	/* Get remote address */
	if (opts.dst_addr) {
		addrlen = fi->dest_addrlen;
		remote_addr = malloc(addrlen);
		memcpy(remote_addr, fi->dest_addr, addrlen);
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

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

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_init_ep(NULL);
	if (ret)
		return ret;

	return 0;
}
Beispiel #14
0
static int init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = get_dupinfo();
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	av_attr.count = ep_cnt;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = alloc_ep();
	if (ret)
		return ret;

	ret = bind_ep_array_res();
	if (ret)
		return ret;

	/* 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)
		return ret;

	ret = init_av();
	return ret;
}
Beispiel #15
0
static int init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = ft_enable_ep_recv();
	if (ret)
		return ret;

	return 0;
}
Beispiel #16
0
static int init_fabric(void)
{
	int ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	/* Check the optimal number of TX and RX contexts supported by the provider */
	ctx_cnt = MIN(ctx_cnt, fi->domain_attr->tx_ctx_cnt);
	ctx_cnt = MIN(ctx_cnt, fi->domain_attr->rx_ctx_cnt);
	if (!ctx_cnt) {
		fprintf(stderr, "Provider doesn't support contexts\n");
		return 1;
	}

	fi->ep_attr->tx_ctx_cnt = ctx_cnt;
	fi->ep_attr->rx_ctx_cnt = ctx_cnt;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = fi_scalable_ep(domain, fi, &sep, NULL);
	if (ret) {
		FT_PRINTERR("fi_scalable_ep", ret);
		return ret;
	}

	ret = alloc_ep_res(sep);
	if (ret)
		return ret;

	ret = bind_ep_res();
	return ret;
}
Beispiel #17
0
int main(int argc, char **argv)
{
	int op, ret;
	int failed;

	hints = fi_allocinfo();
	if (!hints)
		return EXIT_FAILURE;

	while ((op = getopt(argc, argv, "f:d:D:n:a:s:")) != -1) {
		switch (op) {
		case 'd':
			good_address = optarg;
			break;
		case 'D':
			bad_address = optarg;
			break;
		case 'a':
			free(hints->fabric_attr->name);
			hints->fabric_attr->name = strdup(optarg);
			break;
		case 'n':
			num_good_addr = atoi(optarg);
			break;
		case 'f':
			free(hints->fabric_attr->prov_name);
			hints->fabric_attr->prov_name = strdup(optarg);
			break;
		case 's':
			src_addr_str = optarg;
			break;
		default:
			printf("usage: %s\n", argv[0]);
			printf("\t[-d good_address]\n");
			printf("\t[-D bad_address]\n");
			printf("\t[-a fabric_name]\n");
			printf("\t[-n num_good_addr (max=%d)]\n", MAX_ADDR - 1);
			printf("\t[-f provider_name]\n");
			printf("\t[-s source_address]\n");
			return EXIT_FAILURE;

		}
	}

	if (good_address == NULL ||  num_good_addr == 0) {
		printf("Test requires -d  and -n\n");
		return EXIT_FAILURE;
	}

	if (num_good_addr > MAX_ADDR - 1) {
		printf("num_good_addr = %d is too big, dropped to %d\n",
				num_good_addr, MAX_ADDR);
		num_good_addr = MAX_ADDR - 1;
	}

	hints->mode = ~0;
	hints->addr_format = FI_SOCKADDR;

	hints->ep_attr->type = FI_EP_RDM;
	ret = fi_getinfo(FT_FIVERSION, src_addr_str, 0, FI_SOURCE, hints, &fi);
	if (ret != 0 && ret != -FI_ENODATA) {
		printf("fi_getinfo %s\n", fi_strerror(-ret));
		goto err;
	}

	if (ret == -FI_ENODATA) {
		hints->ep_attr->type = FI_EP_DGRAM;
		ret = fi_getinfo(FT_FIVERSION, src_addr_str, 0, FI_SOURCE, hints, &fi);
		if (ret != 0) {
			printf("fi_getinfo %s\n", fi_strerror(-ret));
			goto err;
		}
	}

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	printf("Testing AVs on fabric %s\n", fi->fabric_attr->name);
	failed = 0;

	if (fi->domain_attr->av_type == FI_AV_UNSPEC ||
	    fi->domain_attr->av_type == FI_AV_MAP) {
		av_type = FI_AV_MAP;
		printf("Testing with type = FI_AV_MAP\n");
		failed += run_test_set();
	}

	if (fi->domain_attr->av_type == FI_AV_UNSPEC ||
	    fi->domain_attr->av_type == FI_AV_TABLE) {
		av_type = FI_AV_TABLE;
		printf("Testing with type = FI_AV_TABLE\n");
		failed += run_test_set();
	}

	if (failed > 0) {
		printf("Summary: %d tests failed\n", failed);
	} else {
		printf("Summary: all tests passed\n");
	}

	ft_free_res();
	return (failed > 0);
err:
	ft_free_res();
	return -ret;
}
Beispiel #18
0
int main(int argc, char **argv)
{
	int op, ret;
	int failed = 0;

	buf = NULL;

	hints = fi_allocinfo();
	if (!hints)
		return EXIT_FAILURE;

	while ((op = getopt(argc, argv, FAB_OPTS "h")) != -1) {
		switch (op) {
		default:
			ft_parseinfo(op, optarg, hints, &opts);
			break;
		case '?':
		case 'h':
			usage();
			return EXIT_FAILURE;
		}
	}

	hints->mode = ~0;
	hints->domain_attr->mode = ~0;
	hints->domain_attr->mr_mode = ~(FI_MR_BASIC | FI_MR_SCALABLE);

	hints->caps |= FI_MSG | FI_RMA;

	ret = fi_getinfo(FT_FIVERSION, NULL, 0, 0, hints, &fi);
	if (ret) {
		hints->caps &= ~FI_RMA;
		ret = fi_getinfo(FT_FIVERSION, NULL, 0, 0, hints, &fi);
		if (ret) {
			FT_PRINTERR("fi_getinfo", ret);
			goto out;
		}
	}

	if (!ft_info_to_mr_access(fi))
		goto out;

	if (!fi->domain_attr->mr_iov_limit) {
		ret = -FI_EINVAL;
		FT_PRINTERR("mr_iov_limit not set", ret);
		goto out;
	}

	ret = ft_open_fabric_res();
	if (ret)
		goto out;

	buf = malloc(test_size[test_cnt - 1].size);
	if (!buf) {
		ret = -FI_ENOMEM;
		goto out;
	}

	printf("Testing MR on fabric %s\n", fi->fabric_attr->name);

	failed = run_tests(test_array, err_buf);
	if (failed > 0) {
		printf("Summary: %d tests failed\n", failed);
	} else {
		printf("Summary: all tests passed\n");
	}

out:
	ft_free_res();
	return ret ? ft_exit_code(ret) : (failed > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}
Beispiel #19
0
int main(int argc, char **argv)
{
	char *node, *service;
	uint64_t flags = 0;
	int op, ret;

	opts = INIT_OPTS;

	hints = fi_allocinfo();
	if (!hints)
		exit(1);

	hints->caps = FI_MSG;
	hints->ep_attr->type = FI_EP_MSG;
	hints->mode = FI_LOCAL_MR;
	hints->tx_attr->mode = hints->mode;
	hints->rx_attr->mode = hints->mode;

	hints->ep_attr->max_msg_size = 100;
	hints->tx_attr->size = 10;
	hints->rx_attr->size = 10;

	while ((op = getopt(argc, argv, "c:C:S:h" ADDR_OPTS INFO_OPTS)) != -1) {
		switch (op) {
		case 'c':
			connections = atoi(optarg);
			break;
		case 'C':
			hints->tx_attr->size = atoi(optarg);
			hints->rx_attr->size = hints->tx_attr->size;
			break;
		case 'S':
			hints->ep_attr->max_msg_size = atoi(optarg);
			break;
		default:
			ft_parse_addr_opts(op, optarg, &opts);
			ft_parseinfo(op, optarg, hints);
			break;
		case '?':
		case 'h':
			usage(argv[0]);
		}
	}

	if (optind < argc)
		opts.dst_addr = argv[optind];

	connects_left = connections;

	ret = ft_read_addr_opts(&node, &service, hints, &flags, &opts);
	if (ret)
		goto out;

	ret = fi_getinfo(FT_FIVERSION, node, service, flags, hints, &fi);
	if (ret) {
		FT_PRINTERR("fi_getinfo", ret);
		goto out;
	}

	printf("using provider: %s\n", fi->fabric_attr->prov_name);
	ret = ft_open_fabric_res();
	if (ret)
		goto out;

	if (alloc_nodes())
		goto out;

	ret = opts.dst_addr ? run_client() : run_server();

	printf("test complete\n");
	destroy_nodes();

out:
	ft_free_res();
	return -ret;
}
Beispiel #20
0
static int client_connect(void)
{
	struct fi_eq_cm_entry entry;
	uint32_t event;
	ssize_t rd;
	int i, ret;

	ret = ft_getinfo(hints, &fi);
	if (ret)
		return ret;

	ret = get_dupinfo();
	if (ret)
		return ret;

	ret = ft_open_fabric_res();
	if (ret)
		return ret;

	ret = alloc_ep_res(fi);
	if (ret)
		return ret;

	ret = alloc_ep();
	if (ret)
		return ret;

	ret = bind_ep_array_res();
	if (ret)
		return ret;

	for (i = 0; i < ep_cnt; i++) {
		ret = fi_connect(ep_array[i], fi->dest_addr, NULL, 0);
		if (ret) {
			FT_PRINTERR("fi_connect", ret);
			return 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", "connect");
			ret = (int) rd;
			return ret;
		}

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

	/* 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)
		return ret;

	return 0;
}