static struct sock_conn *sock_conn_map_insert(struct sock_ep *ep, struct sockaddr_in *addr, int conn_fd, int addr_published) { int index; struct sock_conn_map *map = &ep->cmap; if (map->size == map->used) { if (sock_conn_map_increase(map, map->size * 2)) return 0; } index = map->used; map->used++; map->table[index].addr = *addr; map->table[index].sock_fd = conn_fd; map->table[index].ep = ep; sock_set_sockopts(conn_fd); fastlock_acquire(&ep->lock); dlist_insert_tail(&map->table[index].ep_entry, &ep->conn_list); fastlock_release(&ep->lock); if (idm_set(&ep->conn_idm, conn_fd, &map->table[index]) < 0) SOCK_LOG_ERROR("idm_set failed\n"); if (sock_epoll_add(&map->epoll_set, conn_fd)) SOCK_LOG_ERROR("failed to add to epoll set: %d\n", conn_fd); map->table[index].address_published = addr_published; sock_pe_poll_add(ep->domain->pe, conn_fd); return &map->table[index]; }
static int fd_open(void) { struct fd_info *fdi; int ret, index; fdi = calloc(1, sizeof *fdi); if (!fdi) return ERR(ENOMEM); index = open("/dev/null", O_RDONLY); if (index < 0) { ret = index; goto err1; } fdi->dupfd = -1; atomic_init(&fdi->refcnt); atomic_set(&fdi->refcnt, 1); pthread_mutex_lock(&mut); ret = idm_set(&idm, index, fdi); pthread_mutex_unlock(&mut); if (ret < 0) goto err2; return index; err2: real.close(index); err1: free(fdi); return ret; }
static int sock_regattr(struct fid_domain *domain, const struct fi_mr_attr *attr, uint64_t flags, struct fid_mr **mr) { struct fi_eq_entry eq_entry; struct sock_domain *dom; struct sock_mr *_mr; uint64_t key; dom = container_of(domain, struct sock_domain, dom_fid); if (!(dom->info.mode & FI_PROV_MR_ATTR) && ((attr->requested_key > IDX_MAX_INDEX) || idm_lookup(&dom->mr_idm, (int) attr->requested_key))) return -FI_ENOKEY; _mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1)); if (!_mr) return -FI_ENOMEM; _mr->mr_fid.fid.fclass = FI_CLASS_MR; _mr->mr_fid.fid.context = attr->context; _mr->mr_fid.fid.ops = &sock_mr_fi_ops; _mr->domain = dom; _mr->access = attr->access; _mr->flags = flags; _mr->offset = (flags & FI_MR_OFFSET) ? (uintptr_t) attr->mr_iov[0].iov_base + attr->offset : (uintptr_t) attr->mr_iov[0].iov_base; fastlock_acquire(&dom->lock); key = (dom->info.mode & FI_PROV_MR_ATTR) ? sock_get_mr_key(dom) : (uint16_t) attr->requested_key; if (idm_set(&dom->mr_idm, key, _mr) < 0) goto err; _mr->mr_fid.key = key; _mr->mr_fid.mem_desc = (void *)key; fastlock_release(&dom->lock); _mr->iov_count = attr->iov_count; memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count); *mr = &_mr->mr_fid; atomic_inc(&dom->ref); if (dom->mr_eq) { eq_entry.fid = &domain->fid; eq_entry.context = attr->context; return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE, &eq_entry, sizeof(eq_entry), 0); } return 0; err: fastlock_release(&dom->lock); free(_mr); return -errno; }
/* * dup2 is not thread safe */ int dup2(int oldfd, int newfd) { struct fd_info *oldfdi, *newfdi; int ret; init_preload(); oldfdi = idm_lookup(&idm, oldfd); if (oldfdi) { if (oldfdi->state == fd_fork_passive) fork_passive(oldfd); else if (oldfdi->state == fd_fork_active) fork_active(oldfd); } newfdi = idm_lookup(&idm, newfd); if (newfdi) { /* newfd cannot have been dup'ed directly */ if (atomic_get(&newfdi->refcnt) > 1) return ERR(EBUSY); close(newfd); } ret = real.dup2(oldfd, newfd); if (!oldfdi || ret != newfd) return ret; newfdi = calloc(1, sizeof *newfdi); if (!newfdi) { close(newfd); return ERR(ENOMEM); } pthread_mutex_lock(&mut); idm_set(&idm, newfd, newfdi); pthread_mutex_unlock(&mut); newfdi->fd = oldfdi->fd; newfdi->type = oldfdi->type; if (oldfdi->dupfd != -1) { newfdi->dupfd = oldfdi->dupfd; oldfdi = idm_lookup(&idm, oldfdi->dupfd); } else { newfdi->dupfd = oldfd; } atomic_init(&newfdi->refcnt); atomic_set(&newfdi->refcnt, 1); atomic_inc(&oldfdi->refcnt); return newfd; }
static struct sock_conn *sock_conn_map_insert(struct sock_ep_attr *ep_attr, struct sockaddr_in *addr, int conn_fd, int addr_published) { int index; struct sock_conn_map *map = &ep_attr->cmap; if (map->size == map->used) { index = sock_conn_get_next_index(map); if (index < 0) { if (sock_conn_map_increase(map, map->size * 2)) return NULL; index = map->used; } } else { index = map->used; } map->used++; map->table[index].connected = 1; map->table[index].addr = *addr; map->table[index].sock_fd = conn_fd; map->table[index].ep_attr = ep_attr; sock_set_sockopts(conn_fd); if (idm_set(&ep_attr->conn_idm, conn_fd, &map->table[index]) < 0) SOCK_LOG_ERROR("idm_set failed\n"); if (sock_epoll_add(&map->epoll_set, conn_fd)) SOCK_LOG_ERROR("failed to add to epoll set: %d\n", conn_fd); map->table[index].address_published = addr_published; sock_pe_poll_add(ep_attr->domain->pe, conn_fd); return &map->table[index]; }
static int sock_check_table_in(struct sock_av *_av, struct sockaddr_in *addr, fi_addr_t *fi_addr, int count, uint64_t flags, void *context, int index) { void *new_addr; int i, j, ret = 0; char sa_ip[INET_ADDRSTRLEN]; struct sock_av_addr *av_addr; size_t new_count, table_sz, old_sz; if ((_av->attr.flags & FI_EVENT) && !_av->eq) return -FI_ENOEQ; if (_av->attr.flags & FI_READ) { for (i = 0; i < count; i++) { for (j = 0; j < _av->table_hdr->stored; j++) { if (!sock_av_is_valid_address(&addr[i])) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_EINVAL); continue; } av_addr = &_av->table[j]; if (memcmp(&av_addr->addr, &addr[i], sizeof(struct sockaddr_in)) == 0) { SOCK_LOG_DBG("Found addr in shared av\n"); if (idm_set(&_av->addr_idm, _av->key[j], av_addr) < 0) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_EINVAL); continue; } if (fi_addr) fi_addr[i] = (fi_addr_t)j; ret++; } } } sock_av_report_success(_av, context, ret, flags); return (_av->attr.flags & FI_EVENT) ? 0 : ret; } for (i = 0, ret = 0; i < count; i++) { if (_av->table_hdr->stored == _av->table_hdr->size) { if (_av->table_hdr->req_sz) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_ENOSPC); SOCK_LOG_ERROR("Cannot insert to AV table\n"); continue; } else{ new_count = _av->table_hdr->size * 2; _av->key = realloc(_av->key, sizeof(uint16_t) * new_count); if (!_av->key) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_ENOMEM); continue; } table_sz = sizeof(struct sock_av_table_hdr) + new_count * sizeof(struct sock_av_addr); old_sz = sizeof(struct sock_av_table_hdr) + _av->table_hdr->size * sizeof(struct sock_av_addr); if (_av->attr.name) { new_addr = sock_mremap(_av->table_hdr, old_sz, table_sz); if (new_addr == ((void*) -1)) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_ENOMEM); continue; } } else { new_addr = realloc(_av->table_hdr, table_sz); if (!new_addr) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_ENOMEM); continue; } } _av->table_hdr = new_addr; _av->table_hdr->size = new_count; _av->table = (struct sock_av_addr*)((char*)_av->table_hdr + sizeof(struct sock_av_table_hdr)); } } if (!sock_av_is_valid_address(&addr[i])) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_EINVAL); continue; } av_addr = &_av->table[_av->table_hdr->stored]; memcpy(sa_ip, inet_ntoa((&addr[i])->sin_addr), INET_ADDRSTRLEN); SOCK_LOG_DBG("AV-INSERT:dst_addr: family: %d, IP is %s, port: %d\n", ((struct sockaddr_in*)&addr[i])->sin_family, sa_ip, ntohs(((struct sockaddr_in*)&addr[i])->sin_port)); memcpy(&av_addr->addr, &addr[i], sizeof(struct sockaddr_in)); if (idm_set(&_av->addr_idm, _av->table_hdr->stored, av_addr) < 0) { if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; sock_av_report_error(_av, context, i, FI_EINVAL); continue; } if (fi_addr) fi_addr[i] = (fi_addr_t)_av->table_hdr->stored; av_addr->valid = 1; _av->table_hdr->stored++; ret++; } sock_av_report_success(_av, context, ret, flags); return (_av->attr.flags & FI_EVENT) ? 0 : ret; }
struct sock_conn *sock_ep_connect(struct sock_ep *ep, fi_addr_t index) { int conn_fd = -1, ret; int do_retry = sock_conn_retry; struct sock_conn *conn, *new_conn; uint16_t idx; struct sockaddr_in *addr; socklen_t lon; int valopt = 0; struct pollfd poll_fd; if (ep->ep_type == FI_EP_MSG) { idx = 0; addr = ep->dest_addr; } else { idx = index & ep->av->mask; addr = (struct sockaddr_in *)&ep->av->table[idx].addr; } do_connect: fastlock_acquire(&ep->cmap.lock); conn = sock_ep_lookup_conn(ep, index, addr); fastlock_release(&ep->cmap.lock); if (conn != SOCK_CM_CONN_IN_PROGRESS) return conn; conn_fd = socket(AF_INET, SOCK_STREAM, 0); if (conn_fd == -1) { SOCK_LOG_ERROR("failed to create conn_fd, errno: %d\n", errno); errno = FI_EOTHER; return NULL; } ret = fd_set_nonblock(conn_fd); if (ret) { SOCK_LOG_ERROR("failed to set conn_fd nonblocking, errno: %d\n", errno); errno = FI_EOTHER; close(conn_fd); return NULL; } SOCK_LOG_DBG("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)); SOCK_LOG_DBG("Connecting using address:%s\n", inet_ntoa(ep->src_addr->sin_addr)); ret = connect(conn_fd, (struct sockaddr *) addr, sizeof *addr); if (ret < 0) { if (errno == EINPROGRESS) { poll_fd.fd = conn_fd; poll_fd.events = POLLOUT; ret = poll(&poll_fd, 1, 15 * 1000); if (ret < 0) { SOCK_LOG_DBG("poll failed\n"); goto retry; } lon = sizeof(int); ret = getsockopt(conn_fd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); if (ret < 0) { SOCK_LOG_DBG("getsockopt failed: %d, %d\n", ret, conn_fd); goto retry; } if (valopt) { SOCK_LOG_DBG("Error in connection() %d - %s - %d\n", valopt, strerror(valopt), conn_fd); SOCK_LOG_DBG("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)); SOCK_LOG_DBG("Connecting using address:%s\n", inet_ntoa(ep->src_addr->sin_addr)); goto retry; } goto out; } else { SOCK_LOG_DBG("Timeout or error() - %s: %d\n", strerror(errno), conn_fd); SOCK_LOG_DBG("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)); SOCK_LOG_DBG("Connecting using address:%s\n", inet_ntoa(ep->src_addr->sin_addr)); goto retry; } } else { goto out; } retry: do_retry--; sleep(10); if (!do_retry) goto err; if (conn_fd != -1) { close(conn_fd); conn_fd = -1; } SOCK_LOG_ERROR("Connect error, retrying - %s - %d\n", strerror(errno), conn_fd); SOCK_LOG_DBG("Connecting to: %s:%d\n", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)); SOCK_LOG_DBG("Connecting using address:%s\n", inet_ntoa(ep->src_addr->sin_addr)); goto do_connect; out: fastlock_acquire(&ep->cmap.lock); new_conn = sock_conn_map_insert(ep, addr, conn_fd, 0); new_conn->av_index = (ep->ep_type == FI_EP_MSG) ? FI_ADDR_NOTAVAIL : (fi_addr_t) idx; conn = idm_lookup(&ep->av_idm, index); if (conn == SOCK_CM_CONN_IN_PROGRESS) { idm_set(&ep->av_idm, index, new_conn); conn = new_conn; } fastlock_release(&ep->cmap.lock); return conn; err: close(conn_fd); return NULL; }