static int __gnix_getinfo_resolve_node()

in prov/gni/src/gnix_fabric.c [307:445]


static int __gnix_getinfo_resolve_node(const char *node, const char *service,
				       uint64_t flags, const struct fi_info *hints,
				       struct fi_info *info)
{
	int ret;
	struct gnix_ep_name *dest_addr = NULL;
	struct gnix_ep_name *src_addr = NULL;
	bool is_fi_addr_str = false;

	/* TODO: Add version check when we decide on how to do it */
	if (hints && hints->addr_format == FI_ADDR_STR) {
		is_fi_addr_str = true;
	}

	if (OFI_UNLIKELY(is_fi_addr_str && node && service)) {
		GNIX_WARN(FI_LOG_FABRIC, "service parameter must be NULL when "
			"node parameter is not and using FI_ADDR_STR.\n");
		return -FI_EINVAL;
	}

	if (flags & FI_SOURCE) {
		/* -resolve node/port to make info->src_addr
		 * -ignore hints->src_addr
		 * -copy hints->dest_addr to output info */
		src_addr = malloc(sizeof(*src_addr));
		if (!src_addr) {
			ret = -FI_ENOMEM;
			goto err;
		}

		if (is_fi_addr_str) {
			ret = _gnix_ep_name_from_str(node, src_addr);
		} else {
			ret = _gnix_resolve_name(node, service, flags,
						 src_addr);
		}

		if (ret != FI_SUCCESS) {
			ret = -FI_ENODATA;
			goto err;
		}

		if (hints && hints->dest_addr) {
			dest_addr = malloc(sizeof(*dest_addr));
			if (!dest_addr) {
				ret = -FI_ENOMEM;
				goto err;
			}

			memcpy(dest_addr, hints->dest_addr,
			       hints->dest_addrlen);
		}
	} else {
		/* -try to resolve node/port to make info->dest_addr
		 * -fallback to copying hints->dest_addr to output info
		 * -try to copy hints->src_addr to output info
		 * -falback to finding src_addr for output info */
		if (node || service) {
			dest_addr = malloc(sizeof(*dest_addr));
			if (!dest_addr) {
				ret = -FI_ENOMEM;
				goto err;
			}

			if (is_fi_addr_str) {
				ret = _gnix_ep_name_from_str(node, dest_addr);
			} else {
				ret = _gnix_resolve_name(node, service, flags,
							 dest_addr);
			}

			if (ret != FI_SUCCESS) {
				ret = -FI_ENODATA;
				goto err;
			}
		} else {
			if (hints && hints->dest_addr) {
				dest_addr = malloc(sizeof(*dest_addr));
				if (!dest_addr) {
					ret = -FI_ENOMEM;
					goto err;
				}

				memcpy(dest_addr, hints->dest_addr,
				       hints->dest_addrlen);
			}
		}

		if (hints && hints->src_addr) {
			src_addr = malloc(sizeof(*src_addr));
			if (!src_addr) {
				ret = -FI_ENOMEM;
				goto err;
			}

			memcpy(src_addr, hints->src_addr, hints->src_addrlen);
		} else {
			src_addr = malloc(sizeof(*src_addr));
			if (!src_addr) {
				ret = -FI_ENOMEM;
				goto err;
			}

			ret = _gnix_src_addr(src_addr);
			if (ret != FI_SUCCESS)
				goto err;
		}
	}

	GNIX_INFO(FI_LOG_FABRIC, "%snode: %s service: %s\n",
		  flags & FI_SOURCE ? "(FI_SOURCE) " : "", node, service);

	if (src_addr)
		GNIX_INFO(FI_LOG_FABRIC, "src_pe: 0x%x src_port: 0x%lx\n",
			  src_addr->gnix_addr.device_addr,
			  src_addr->gnix_addr.cdm_id);
	if (dest_addr)
		GNIX_INFO(FI_LOG_FABRIC, "dest_pe: 0x%x dest_port: 0x%lx\n",
			  dest_addr->gnix_addr.device_addr,
			  dest_addr->gnix_addr.cdm_id);

	if (src_addr) {
		info->src_addr = src_addr;
		info->src_addrlen = sizeof(*src_addr);
	}

	if (dest_addr) {
		info->dest_addr = dest_addr;
		info->dest_addrlen = sizeof(*dest_addr);
	}

	return FI_SUCCESS;

err:
	free(src_addr);
	free(dest_addr);

	return ret;
}