Exemple #1
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 (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;
				table_sz = SOCK_AV_TABLE_SZ(new_count, _av->attr.name);
				old_sz = SOCK_AV_TABLE_SZ(_av->table_hdr->size, _av->attr.name);

				if (_av->attr.name) {
					new_addr = sock_mremap(_av->table_hdr,
							       old_sz, table_sz);
					if (new_addr == MAP_FAILED) {
						if (fi_addr)
							fi_addr[i] = FI_ADDR_NOTAVAIL;
						sock_av_report_error(_av,
							context, i, FI_ENOMEM);
						continue;
					}
					_av->idx_arr[_av->table_hdr->stored] = _av->table_hdr->stored;
				} 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;
				sock_update_av_table(_av, new_count);
			}
		}

		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 (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;
}
Exemple #2
0
int sock_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
		 struct fid_av **av, void *context)
{
	int ret = 0;
	struct sock_domain *dom;
	struct sock_av *_av;
	size_t table_sz;

	if (!attr || sock_verify_av_attr(attr))
		return -FI_EINVAL;

	if (attr->type == FI_AV_UNSPEC)
		attr->type = FI_AV_TABLE;

	dom = container_of(domain, struct sock_domain, dom_fid);
	if (dom->attr.av_type != FI_AV_UNSPEC &&
	    dom->attr.av_type != attr->type)
		return -FI_EINVAL;

	_av = calloc(1, sizeof(*_av));
	if (!_av)
		return -FI_ENOMEM;

	_av->attr = *attr;
	_av->attr.count = (attr->count) ? attr->count : sock_av_def_sz;
	table_sz = SOCK_AV_TABLE_SZ(_av->attr.count, attr->name);

	if (attr->name) {
		ret = ofi_shm_map(&_av->shm, attr->name, table_sz,
				attr->flags & FI_READ, (void**)&_av->table_hdr);

		if (ret || _av->table_hdr == MAP_FAILED) {
			SOCK_LOG_ERROR("map failed\n");
			ret = -FI_EINVAL;
			goto err;
		}

		_av->idx_arr = (uint64_t *)(_av->table_hdr + 1);
		_av->attr.map_addr = _av->idx_arr;
		attr->map_addr = _av->attr.map_addr;
		SOCK_LOG_DBG("Updating map_addr: %p\n", _av->attr.map_addr);

		if (attr->flags & FI_READ) {
			if (_av->table_hdr->size != _av->attr.count) {
				ret = -FI_EINVAL;
				goto err2;
			}
		} else {
			_av->table_hdr->size = _av->attr.count;
			_av->table_hdr->stored = 0;
		}
		_av->shared = 1;
	} else {
		_av->table_hdr = calloc(1, table_sz);
		if (!_av->table_hdr) {
			ret = -FI_ENOMEM;
			goto err;
		}
		_av->table_hdr->size = _av->attr.count;
		_av->table_hdr->req_sz = attr->count;
	}
	sock_update_av_table(_av, _av->attr.count);

	_av->av_fid.fid.fclass = FI_CLASS_AV;
	_av->av_fid.fid.context = context;
	_av->av_fid.fid.ops = &sock_av_fi_ops;

	switch (attr->type) {
	case FI_AV_MAP:
		_av->av_fid.ops = &sock_am_ops;
		break;
	case FI_AV_TABLE:
		_av->av_fid.ops = &sock_at_ops;
		break;
	default:
		ret = -FI_EINVAL;
		goto err2;
	}

	atomic_initialize(&_av->ref, 0);
	atomic_inc(&dom->ref);
	_av->domain = dom;
	switch (dom->info.addr_format) {
	case FI_SOCKADDR_IN:
		_av->addrlen = sizeof(struct sockaddr_in);
		break;
	default:
		SOCK_LOG_ERROR("Invalid address format: only IPv4 supported\n");
		ret = -FI_EINVAL;
		goto err2;
	}
	_av->rx_ctx_bits = attr->rx_ctx_bits;
	_av->mask = attr->rx_ctx_bits ?
		((uint64_t)1 << (64 - attr->rx_ctx_bits)) - 1 : ~0;
	*av = &_av->av_fid;
	return 0;

err2:
	if(attr->name) {
		ofi_shm_unmap(&_av->shm);
	} else {
		if(_av->table_hdr && _av->table_hdr != MAP_FAILED)
			free(_av->table_hdr);
	}
err:
	free(_av);
	return ret;
}
Exemple #3
0
int sock_av_open(struct fid_domain *domain, struct fi_av_attr *attr,
                 struct fid_av **av, void *context)
{
    int ret = 0;
    struct sock_domain *dom;
    struct sock_av *_av;
    size_t table_sz, i;
    int flags = O_RDWR;
    struct stat mapstat;

    if (!attr || sock_verify_av_attr(attr))
        return -FI_EINVAL;

    if (attr && attr->type == FI_AV_UNSPEC)
        attr->type = FI_AV_TABLE;

    dom = container_of(domain, struct sock_domain, dom_fid);
    if (dom->attr.av_type != FI_AV_UNSPEC && attr &&
            dom->attr.av_type != attr->type)
        return -FI_EINVAL;

    _av = calloc(1, sizeof(*_av));
    if (!_av)
        return -FI_ENOMEM;

    _av->attr = *attr;
    _av->attr.count = (attr->count) ? attr->count : sock_av_def_sz;
    table_sz = SOCK_AV_TABLE_SZ(_av->attr.count, attr->name);

    if (attr->name) {
        _av->name = calloc(1, strlen(attr->name) + 1);
        if (!_av->name) {
            ret = -FI_ENOMEM;
            goto err1;
        }
        sprintf(_av->name, "/%s", attr->name);
        if (!(attr->flags & FI_READ))
            flags |= O_CREAT;

        for (i = 0; i < strlen(_av->name); i++)
            if (_av->name[i] == ' ')
                _av->name[i] = '_';

        SOCK_LOG_DBG("Creating shm segment :%s (size: %lu)\n",
                     _av->name, table_sz);

        _av->shared_fd = shm_open(_av->name, flags, S_IRUSR | S_IWUSR);
        if (_av->shared_fd < 0) {
            SOCK_LOG_ERROR("shm_open failed\n");
            ret = -FI_EINVAL;
            goto err2;
        }

        if (fstat(_av->shared_fd, &mapstat)) {
            SOCK_LOG_ERROR("failed to do fstat: %s\n", strerror(errno));
            goto err_shm;
        }

        if (mapstat.st_size == 0) {
            if (ftruncate(_av->shared_fd, table_sz)) {
                SOCK_LOG_ERROR("ftruncate failed: %s\n", strerror(errno));
                goto err_shm;
            }
        } else if (mapstat.st_size < table_sz) {
            SOCK_LOG_ERROR("shm file too small\n");
            goto err_shm;
        }

        _av->table_hdr = mmap(NULL, table_sz, PROT_READ | PROT_WRITE,
                              MAP_SHARED, _av->shared_fd, 0);
        _av->idx_arr = (uint64_t *)(_av->table_hdr + 1);
        _av->attr.map_addr = _av->idx_arr;
        attr->map_addr = _av->attr.map_addr;
        SOCK_LOG_DBG("Updating map_addr: %p\n", _av->attr.map_addr);

        if (attr->flags & FI_READ) {
            if (_av->table_hdr->size != _av->attr.count) {
                ret = -FI_EINVAL;
                goto err2;
            }
        } else {
            _av->table_hdr->size = _av->attr.count;
            _av->table_hdr->stored = 0;
        }

        if (_av->table_hdr == MAP_FAILED) {
            SOCK_LOG_ERROR("mmap failed\n");
            shm_unlink(_av->name);
            ret = -FI_EINVAL;
            goto err2;
        }
    } else {
        _av->table_hdr = calloc(1, table_sz);
        if (!_av->table_hdr) {
            ret = -FI_ENOMEM;
            goto err3;
        }
        _av->table_hdr->size = _av->attr.count;
        _av->table_hdr->req_sz = attr->count;
    }
    sock_update_av_table(_av, _av->attr.count);

    _av->av_fid.fid.fclass = FI_CLASS_AV;
    _av->av_fid.fid.context = context;
    _av->av_fid.fid.ops = &sock_av_fi_ops;

    switch (attr->type) {
    case FI_AV_MAP:
        _av->av_fid.ops = &sock_am_ops;
        break;
    case FI_AV_TABLE:
        _av->av_fid.ops = &sock_at_ops;
        break;
    default:
        ret = -FI_EINVAL;
        goto err3;
    }

    atomic_initialize(&_av->ref, 0);
    atomic_inc(&dom->ref);
    _av->domain = dom;
    switch (dom->info.addr_format) {
    case FI_SOCKADDR_IN:
        _av->addrlen = sizeof(struct sockaddr_in);
        break;
    default:
        SOCK_LOG_ERROR("Invalid address format: only IPv4 supported\n");
        ret = -FI_EINVAL;
        goto err3;
    }
    _av->rx_ctx_bits = attr->rx_ctx_bits;
    _av->mask = attr->rx_ctx_bits ?
                ((uint64_t)1 << (64 - attr->rx_ctx_bits)) - 1 : ~0;
    *av = &_av->av_fid;
    return 0;

err_shm:
    shm_unlink(_av->name);
    ret = -FI_EINVAL;
    goto err2;
err3:
    free(_av->table_hdr);
err2:
    free(_av->name);
err1:
    free(_av);

    return ret;
}