static int sock_getinfo(uint32_t version, const char *node, const char *service, uint64_t flags, struct fi_info *hints, struct fi_info **info) { int ret; struct fi_info *_info, *tmp; return -FI_ENODATA; ret = sock_verify_info(hints); if (ret) return ret; if (hints) { switch (hints->ep_type) { case FI_EP_RDM: return sock_rdm_getinfo(version, node, service, flags, hints, info); case FI_EP_DGRAM: return sock_dgram_getinfo(version, node, service, flags, hints, info); default: break; } } ret = sock_rdm_getinfo(version, node, service, flags, hints, &_info); if (ret == 0) { *info = tmp = _info; while(tmp->next != NULL) tmp=tmp->next; } else if (ret == -FI_ENODATA) { tmp = NULL; } else return ret; ret = sock_dgram_getinfo(version, node, service, flags, hints, &_info); if (NULL != tmp) { tmp->next = _info; return ret; } *info = _info; return ret; }
static struct fi_info * sock_ep_msg_process_info(struct sock_conn_req *req) { req->info.src_addr = &req->src_addr; req->info.dest_addr = &req->dest_addr; req->info.tx_attr = &req->tx_attr; req->info.rx_attr = &req->rx_attr; req->info.ep_attr = &req->ep_attr; req->info.domain_attr = &req->domain_attr; req->info.fabric_attr = &req->fabric_attr; req->info.domain_attr->name = NULL; req->info.fabric_attr->name = NULL; req->info.fabric_attr->prov_name = NULL; if (sock_verify_info(&req->info)) { SOCK_LOG_INFO("incoming conn_req not supported\n"); errno = EINVAL; return NULL; } return sock_fi_info(FI_EP_MSG, &req->info, req->info.dest_addr, req->info.src_addr); }
int sock_msg_passive_ep(struct fid_fabric *fabric, struct fi_info *info, struct fid_pep **pep, void *context) { int ret, flags; struct sock_pep *_pep; char hostname[HOST_NAME_MAX]; struct addrinfo sock_hints; struct addrinfo *result = NULL; if (info) { ret = sock_verify_info(info); if (ret) { SOCK_LOG_INFO("Cannot support requested options!\n"); return -FI_EINVAL; } } _pep = (struct sock_pep*)calloc(1, sizeof(*_pep)); if (!_pep) return -FI_ENOMEM; if(info) { if (info->src_addr) { memcpy(&_pep->src_addr, info->src_addr, sizeof(struct sockaddr_in)); } else { gethostname(hostname, HOST_NAME_MAX); memset(&sock_hints, 0, sizeof(struct addrinfo)); sock_hints.ai_family = AF_INET; sock_hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(hostname, NULL, &sock_hints, &result); if (ret != 0) { ret = FI_EINVAL; SOCK_LOG_INFO("getaddrinfo failed!\n"); goto err; } memcpy(&_pep->src_addr, result->ai_addr, result->ai_addrlen); } _pep->info = *info; } else { SOCK_LOG_ERROR("invalid fi_info\n"); goto err; } if(socketpair(AF_UNIX, SOCK_STREAM, 0, _pep->signal_fds) < 0) goto err; flags = fcntl(_pep->signal_fds[1], F_GETFL, 0); fcntl(_pep->signal_fds[1], F_SETFL, flags | O_NONBLOCK); _pep->pep.fid.fclass = FI_CLASS_PEP; _pep->pep.fid.context = context; _pep->pep.fid.ops = &sock_pep_fi_ops; _pep->pep.cm = &sock_pep_cm_ops; _pep->pep.ops = NULL; _pep->sock_fab = container_of(fabric, struct sock_fabric, fab_fid); *pep = &_pep->pep; return 0; err: free(_pep); return ret; }
int sock_alloc_endpoint(struct fid_domain *domain, struct fi_info *info, struct sock_ep **ep, void *context, size_t fclass) { int ret, flags; struct sock_ep *sock_ep; struct sock_tx_ctx *tx_ctx; struct sock_rx_ctx *rx_ctx; struct sock_domain *sock_dom; if (info) { ret = sock_verify_info(info); if (ret) { SOCK_LOG_INFO("Cannot support requested options!\n"); return -FI_EINVAL; } } sock_dom = container_of(domain, struct sock_domain, dom_fid); sock_ep = (struct sock_ep*)calloc(1, sizeof(*sock_ep)); if (!sock_ep) return -FI_ENOMEM; switch (fclass) { case FI_CLASS_EP: sock_ep->ep.fid.fclass = FI_CLASS_EP; sock_ep->ep.fid.context = context; sock_ep->ep.fid.ops = &sock_ep_fi_ops; sock_ep->ep.ops = &sock_ep_ops; sock_ep->ep.cm = &sock_ep_cm_ops; sock_ep->ep.msg = &sock_ep_msg_ops; sock_ep->ep.rma = &sock_ep_rma; sock_ep->ep.tagged = &sock_ep_tagged; sock_ep->ep.atomic = &sock_ep_atomic; break; case FI_CLASS_SEP: sock_ep->ep.fid.fclass = FI_CLASS_SEP; sock_ep->ep.fid.context = context; sock_ep->ep.fid.ops = &sock_ep_fi_ops; sock_ep->ep.ops = &sock_ep_ops; sock_ep->ep.cm = &sock_ep_cm_ops; break; default: goto err; } sock_ep->fclass = fclass; *ep = sock_ep; fastlock_acquire(&sock_dom->lock); fastlock_release(&sock_dom->lock); if (info) { sock_ep->info.caps = info->caps; sock_ep->info.addr_format = FI_SOCKADDR_IN; if (info->ep_attr) { sock_ep->ep_type = info->ep_attr->type; sock_ep->ep_attr.tx_ctx_cnt = info->ep_attr->tx_ctx_cnt; sock_ep->ep_attr.rx_ctx_cnt = info->ep_attr->rx_ctx_cnt; } if (info->src_addr) { sock_ep->src_addr = calloc(1, sizeof(struct sockaddr_in)); memcpy(sock_ep->src_addr, info->src_addr, sizeof(struct sockaddr_in)); } if (info->dest_addr) { sock_ep->dest_addr = calloc(1, sizeof(struct sockaddr_in)); memcpy(sock_ep->dest_addr, info->dest_addr, sizeof(struct sockaddr_in)); } if (info->tx_attr) { sock_ep->tx_attr = *info->tx_attr; sock_ep->op_flags = info->tx_attr->op_flags; sock_ep->tx_attr.size = sock_ep->tx_attr.size ? sock_ep->tx_attr.size : (SOCK_EP_TX_SZ * SOCK_EP_TX_ENTRY_SZ); } if (info->rx_attr) { sock_ep->rx_attr = *info->rx_attr; sock_ep->op_flags |= info->rx_attr->op_flags; sock_ep->rx_attr.total_buffered_recv = sock_ep->rx_attr.total_buffered_recv ? sock_ep->rx_attr.total_buffered_recv : SOCK_EP_MAX_BUFF_RECV; } sock_ep->info.connreq = info->connreq; } atomic_init(&sock_ep->ref, 0); atomic_init(&sock_ep->num_tx_ctx, 0); atomic_init(&sock_ep->num_rx_ctx, 0); if (sock_ep->ep_attr.tx_ctx_cnt == FI_SHARED_CONTEXT) sock_ep->tx_shared = 1; if (sock_ep->ep_attr.rx_ctx_cnt == FI_SHARED_CONTEXT) sock_ep->rx_shared = 1; if (sock_ep->fclass != FI_CLASS_SEP) { sock_ep->ep_attr.tx_ctx_cnt = 1; sock_ep->ep_attr.rx_ctx_cnt = 1; } sock_ep->tx_array = calloc(sock_ep->ep_attr.tx_ctx_cnt, sizeof(struct sock_tx_ctx *)); sock_ep->rx_array = calloc(sock_ep->ep_attr.rx_ctx_cnt, sizeof(struct sock_rx_ctx *)); if (sock_ep->fclass != FI_CLASS_SEP && sock_ep->ep_attr.tx_ctx_cnt != FI_SHARED_CONTEXT) { /* default tx ctx */ tx_ctx = sock_tx_ctx_alloc(&sock_ep->tx_attr, context); tx_ctx->ep = sock_ep; tx_ctx->domain = sock_dom; tx_ctx->tx_id = 0; dlist_insert_tail(&sock_ep->tx_ctx_entry, &tx_ctx->ep_list); sock_ep->tx_array[0] = tx_ctx; sock_ep->tx_ctx = tx_ctx; } if (sock_ep->fclass != FI_CLASS_SEP && sock_ep->ep_attr.rx_ctx_cnt != FI_SHARED_CONTEXT) { /* default rx_ctx */ rx_ctx = sock_rx_ctx_alloc(&sock_ep->rx_attr, context); rx_ctx->ep = sock_ep; rx_ctx->domain = sock_dom; rx_ctx->rx_id = 0; dlist_insert_tail(&sock_ep->rx_ctx_entry, &rx_ctx->ep_list); sock_ep->rx_array[0] = rx_ctx; sock_ep->rx_ctx = rx_ctx; } /* default config */ sock_ep->min_multi_recv = SOCK_EP_MIN_MULTI_RECV; if (info) { memcpy(&sock_ep->info, info, sizeof(struct fi_info)); } sock_ep->domain = sock_dom; if (sock_conn_listen(sock_ep)) goto err; if (sock_ep->ep_type == FI_EP_MSG) { dlist_init(&sock_ep->cm.msg_list); if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock_ep->cm.signal_fds) < 0) goto err; flags = fcntl(sock_ep->cm.signal_fds[1], F_GETFL, 0); if (fcntl(sock_ep->cm.signal_fds[1], F_SETFL, flags | O_NONBLOCK)) SOCK_LOG_ERROR("fcntl failed"); } atomic_inc(&sock_dom->ref); return 0; err: free(sock_ep); return -FI_EINVAL; }