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];
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
/*
 * 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;
}
Exemple #5
0
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];
}
Exemple #6
0
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;
}