static int usdf_pep_bind(fid_t fid, fid_t bfid, uint64_t flags) { struct usdf_pep *pep; USDF_TRACE_SYS(EP_CTRL, "\n"); pep = pep_fidtou(fid); switch (bfid->fclass) { case FI_CLASS_EQ: if (pep->pep_eq != NULL) { return -FI_EINVAL; } pep->pep_eq = eq_fidtou(bfid); atomic_inc(&pep->pep_eq->eq_refcnt); break; default: return -FI_EINVAL; } return 0; }
int usdf_pep_close(fid_t fid) { struct usdf_pep *pep; pep = pep_fidtou(fid); if (atomic_get(&pep->pep_refcnt) > 0) { return -FI_EBUSY; } usdf_pep_free_cr_lists(pep); close(pep->pep_sock); if (&pep->pep_eq != NULL) { atomic_dec(&pep->pep_eq->eq_refcnt); } atomic_dec(&pep->pep_fabric->fab_refcnt); free(pep); return 0; }
static int usdf_pep_getname(fid_t fid, void *addr, size_t *addrlen) { int ret; struct usdf_pep *pep; size_t copylen; USDF_TRACE_SYS(EP_CTRL, "\n"); ret = FI_SUCCESS; pep = pep_fidtou(fid); copylen = sizeof(pep->pep_src_addr); memcpy(addr, &pep->pep_src_addr, MIN(copylen, *addrlen)); if (*addrlen < copylen) { USDF_WARN_SYS(EP_CTRL, "*addrlen is too short\n"); ret = -FI_ETOOSMALL; } *addrlen = copylen; return ret; }
static int usdf_pep_close(fid_t fid) { struct usdf_pep *pep; USDF_TRACE_SYS(EP_CTRL, "\n"); pep = pep_fidtou(fid); if (atomic_get(&pep->pep_refcnt) > 0) { return -FI_EBUSY; } usdf_pep_free_cr_lists(pep); close(pep->pep_sock); pep->pep_sock = -1; if (pep->pep_eq != NULL) { atomic_dec(&pep->pep_eq->eq_refcnt); } atomic_dec(&pep->pep_fabric->fab_refcnt); free(pep); return 0; }
static int usdf_pep_setname(fid_t fid, void *addr, size_t addrlen) { int ret; struct usdf_pep *pep; uint32_t req_addr_be; socklen_t socklen; char namebuf[INET_ADDRSTRLEN]; char servbuf[INET_ADDRSTRLEN]; USDF_TRACE_SYS(EP_CTRL, "\n"); pep = pep_fidtou(fid); if (pep->pep_state != USDF_PEP_UNBOUND) { USDF_WARN_SYS(EP_CTRL, "PEP cannot be bound\n"); return -FI_EOPBADSTATE; } if (((struct sockaddr *)addr)->sa_family != AF_INET) { USDF_WARN_SYS(EP_CTRL, "non-AF_INET address given\n"); return -FI_EINVAL; } if (addrlen != sizeof(struct sockaddr_in)) { USDF_WARN_SYS(EP_CTRL, "unexpected src_addrlen\n"); return -FI_EINVAL; } req_addr_be = ((struct sockaddr_in *)addr)->sin_addr.s_addr; namebuf[0] = '\0'; servbuf[0] = '\0'; ret = getnameinfo((struct sockaddr*)addr, addrlen, namebuf, sizeof(namebuf), servbuf, sizeof(servbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (ret != 0) USDF_WARN_SYS(EP_CTRL, "unable to getnameinfo(0x%x)\n", req_addr_be); if (req_addr_be != pep->pep_fabric->fab_dev_attrs->uda_ipaddr_be) { USDF_WARN_SYS(EP_CTRL, "requested addr (%s:%s) does not match fabric addr\n", namebuf, servbuf); return -FI_EADDRNOTAVAIL; } ret = bind(pep->pep_sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); if (ret == -1) { return -errno; } pep->pep_state = USDF_PEP_BOUND; /* store the resulting port so that can implement getname() properly */ socklen = sizeof(pep->pep_src_addr); ret = getsockname(pep->pep_sock, &pep->pep_src_addr, &socklen); if (ret == -1) { ret = -errno; USDF_WARN_SYS(EP_CTRL, "getsockname failed %d (%s), PEP may be in bad state\n", ret, strerror(-ret)); return ret; } return 0; }