Exemplo n.º 1
0
static int sock_ep_cm_accept(struct fid_ep *ep, const void *param, size_t paramlen)
{
	struct sock_conn_req *req;
	struct fi_eq_cm_entry cm_entry;
	struct sock_conn_response *response;
	struct sockaddr_in *addr;
	struct sock_ep *_ep;
	struct sock_eq *_eq;
	int ret;

	_ep = container_of(ep, struct sock_ep, ep);
	_eq = _ep->eq;
	if (!_eq || paramlen > SOCK_EP_MAX_CM_DATA_SZ) 
		return -FI_EINVAL;

	response = (struct sock_conn_response*)calloc(1, 
						 sizeof(*response) + paramlen);
	if (!response)
		return -FI_ENOMEM;

	req = (struct sock_conn_req *)_ep->info.connreq;
	if (!req) {
		SOCK_LOG_ERROR("invalid connreq for cm_accept\n");
		return -FI_EINVAL;
	}
	
	memcpy(&response->hdr, &req->hdr, sizeof(struct sock_conn_hdr));
	if (param && paramlen)
		memcpy(&response->user_data, param, paramlen);

	addr = &req->from_addr;
	_ep->rem_ep_id = req->ep_id;
	response->hdr.type = SOCK_CONN_ACCEPT;
	response->hdr.s_fid = &ep->fid;

	_ep->socket = sock_ep_cm_create_socket();
	if (!_ep->socket) {
		ret = -FI_EIO;
		goto out;
	}
	
	if (sock_ep_cm_send_msg(_ep->socket, addr, response, 
				sizeof (*response) + paramlen)) {
		close(_ep->socket);
		ret = -FI_EIO;
		goto out;
	}
	    
	sock_ep_enable(ep);
	memset(&cm_entry, 0, sizeof(cm_entry));
	cm_entry.fid = &ep->fid;
	_ep->connected = 1;
	ret = sock_eq_report_event(_eq, FI_CONNECTED, &cm_entry, 
				   sizeof(cm_entry), 0);
out:
	free(req);
	free(response);
	_ep->info.connreq = NULL;
	return ret;
}
Exemplo n.º 2
0
static int sock_ep_control(struct fid *fid, int command, void *arg)
{
	struct fid_ep *ep_fid;
	struct fi_alias *alias;
	struct sock_ep *ep, *new_ep;

	switch(fid->fclass) {
	case FI_CLASS_EP:
		ep = container_of(fid, struct sock_ep, ep.fid);
		break;

	case FI_CLASS_SEP:
		ep = container_of(fid, struct sock_ep, ep.fid);
		break;

	default:
		return -FI_EINVAL;
	}

	switch (command) {
	case FI_ALIAS:
		alias = (struct fi_alias*)arg;
		new_ep = calloc(1, sizeof(*new_ep));
		if (!new_ep)
			return -FI_ENOMEM;
		*new_ep = *ep;
		new_ep->op_flags = alias->flags;
		*alias->fid = &new_ep->ep.fid;
		break;

	case FI_GETOPSFLAG:
		*(uint64_t *) arg = ep->op_flags;
		break;
	case FI_SETOPSFLAG:
		ep->op_flags = *(uint64_t *) arg;
		break;
	case FI_ENABLE:
		ep_fid = container_of(fid, struct fid_ep, fid);
		return sock_ep_enable(ep_fid);

	default:
		return -FI_EINVAL;
	}
	return 0;
}
Exemplo n.º 3
0
static int sock_ep_control(struct fid *fid, int command, void *arg)
{
	int ret;
	struct fid_ep *ep_fid;
	struct fi_alias *alias;
	struct sock_ep *sock_ep, *new_ep;

	switch (fid->fclass) {
	case FI_CLASS_EP:
		sock_ep = container_of(fid, struct sock_ep, ep.fid);
		break;

	case FI_CLASS_SEP:
		sock_ep = container_of(fid, struct sock_ep, ep.fid);
		break;

	default:
		return -FI_EINVAL;
	}

	switch (command) {
	case FI_ALIAS:
		alias = (struct fi_alias *)arg;
		new_ep = calloc(1, sizeof(*new_ep));
		if (!new_ep)
			return -FI_ENOMEM;

		memcpy(&new_ep->tx_attr, &sock_ep->tx_attr, sizeof(struct fi_tx_attr));
		memcpy(&new_ep->rx_attr, &sock_ep->rx_attr, sizeof(struct fi_rx_attr));
		ret = sock_setopflags(&new_ep->tx_attr, &new_ep->rx_attr,
				       alias->flags);
		if (ret) {
			free(new_ep);
			return -FI_EINVAL;
		}
		new_ep->attr = sock_ep->attr;
		new_ep->is_alias = 1;
		memcpy(&new_ep->ep, &sock_ep->ep, sizeof(struct fid_ep));
		*alias->fid = &new_ep->ep.fid;
		atomic_inc(&new_ep->attr->ref);
		break;
	case FI_GETOPSFLAG:
		ret = sock_getopflags(&sock_ep->tx_attr, &sock_ep->rx_attr, (uint64_t *) arg);
		if (ret)
			return -EINVAL;
		break;
	case FI_SETOPSFLAG:
		ret = sock_setopflags(&sock_ep->tx_attr, &sock_ep->rx_attr, *(uint64_t *) arg);
		if (ret)
			return -FI_EINVAL;
		break;
		break;
	case FI_ENABLE:
		ep_fid = container_of(fid, struct fid_ep, fid);
		return sock_ep_enable(ep_fid);

	default:
		return -FI_EINVAL;
	}
	return 0;
}
Exemplo n.º 4
0
static void *sock_msg_ep_listener_thread (void *data)
{
	struct sock_ep *ep = (struct sock_ep *)data;
	struct sock_conn_response *conn_response = NULL;

	struct fi_eq_cm_entry cm_entry;
	struct fi_eq_err_entry cm_err_entry;

	struct sockaddr_in from_addr;
	socklen_t addr_len;
	int ret, user_data_sz;
	struct fid_ep *fid_ep;
	struct sock_ep *sock_ep;

	SOCK_LOG_INFO("Starting listener thread for EP: %p\n", ep);
	ep->do_listen = 1;

	while((volatile int)ep->do_listen) {
		ret = fi_poll_fd(ep->socket, -1);
		if (ret <= 0)
			continue;
		
		if (conn_response == NULL) {
			conn_response = (struct sock_conn_response*)
				calloc(1, sizeof(*conn_response) + 
				       SOCK_EP_MAX_CM_DATA_SZ);
			if (!conn_response) {
				SOCK_LOG_ERROR("cannot allocate\n");
				return NULL;
			}
		}
		
		addr_len = sizeof(struct sockaddr_in);
		ret = recvfrom(ep->socket, (char*)conn_response, 
			       sizeof(*conn_response) + SOCK_EP_MAX_CM_DATA_SZ,
			       0, (struct sockaddr *) &from_addr, &addr_len);
		if (ret <= 0)
			continue;
		
		SOCK_LOG_INFO("Total received: %d\n", ret);
		
		if (ret < sizeof(*conn_response) || 
		    !sock_ep_cm_send_ack(ep->socket, &from_addr))
			continue;

		user_data_sz = 0;
		switch (conn_response->hdr.type) {
			
		case SOCK_CONN_ACCEPT:
			SOCK_LOG_INFO("Received SOCK_CONN_ACCEPT\n");
			memset(&cm_entry, 0, sizeof(cm_entry));
			cm_entry.fid = conn_response->hdr.c_fid;

			if (ret > sizeof(struct sock_conn_response)) {
				user_data_sz = ret - 
					sizeof(struct sock_conn_response);
				memcpy(&cm_entry.data,
				       (char *)conn_response + 
				       sizeof(struct sock_conn_response),
				       user_data_sz);
			}

			fid_ep = container_of(conn_response->hdr.c_fid, 
					      struct fid_ep, fid);
			sock_ep = container_of(fid_ep, struct sock_ep, ep);
			sock_ep->connected = 1;
			sock_ep_enable(&ep->ep);
			if (sock_eq_report_event(ep->eq, FI_CONNECTED, &cm_entry, 
						 sizeof(cm_entry) + user_data_sz, 0)) 
				SOCK_LOG_ERROR("Error in writing to EQ\n");
			break;

		case SOCK_CONN_REJECT:
			SOCK_LOG_INFO("Received SOCK_CONN_REJECT\n");
			memset(&cm_err_entry, 0, sizeof(cm_err_entry));
			cm_err_entry.fid = conn_response->hdr.c_fid;
			cm_err_entry.context = NULL;
			cm_err_entry.data = 0;
			cm_err_entry.err = -FI_ECONNREFUSED;
			cm_err_entry.prov_errno = 0;
			cm_err_entry.err_data = NULL;

			if (ret > sizeof(struct sock_conn_response)) {
				user_data_sz = ret - 
					sizeof(struct sock_conn_response);
				memcpy(&cm_entry.data,
				       (char *)conn_response + 
				       sizeof(struct sock_conn_response),
				       user_data_sz);
			}

			if (sock_eq_report_event(ep->eq, FI_ECONNREFUSED, 
						 &cm_err_entry, 
						 sizeof (cm_err_entry) + 
						 user_data_sz, 0))
				SOCK_LOG_ERROR("Error in writing to EQ\n");
			goto out;

		default:
			SOCK_LOG_ERROR("Invalid event\n");
			break;
		}
		conn_response = NULL;
	}

out:
	if (conn_response)
		free(conn_response);
	close(ep->socket);
	ep->socket = 0;
	return NULL;
}