int ofix_getinfo(uint32_t version, const char *node, const char *service, uint64_t flags, const struct util_prov *util_prov, struct fi_info *hints, ofi_alter_info_t alter_layer_info, ofi_alter_info_t alter_base_info, int get_base_info, struct fi_info **info) { struct fi_info *base_hints = NULL, *base_info; struct fi_info *temp = NULL, *fi, *tail = NULL; int ret; ret = ofi_check_info(util_prov, hints, FI_MATCH_PREFIX); if (ret) goto err1; ret = ofix_alter_layer_info(util_prov->prov, util_prov->info, hints, alter_layer_info, &base_hints); if (ret) goto err1; ret = fi_getinfo(version, node, service, flags, base_hints, &base_info); if (ret) goto err2; if (get_base_info) { *info = base_info; } else { for (fi = base_info; fi; fi = fi->next) { ret = ofix_alter_base_info(util_prov->prov, util_prov->info, fi, alter_base_info, &temp); if (ret) goto err3; ofi_alter_info(temp, hints); if (!tail) *info = temp; else tail->next = temp; tail = temp; } fi_freeinfo(base_info); } fi_freeinfo(base_hints); return 0; err3: fi_freeinfo(*info); err2: fi_freeinfo(base_hints); err1: return -FI_ENODATA; }
/* if there are multiple fi_info in the provider: * check provider's info */ int ofi_prov_check_info(const struct util_prov *util_prov, uint32_t api_version, const struct fi_info *user_info) { const struct fi_info *prov_info = util_prov->info; size_t success_info = 0; int ret; if (!user_info) return FI_SUCCESS; for ( ; prov_info; prov_info = prov_info->next) { ret = ofi_check_info(util_prov, prov_info, api_version, user_info); if (!ret) success_info++; } return (!success_info ? -FI_ENODATA : FI_SUCCESS); }
/* if there are multiple fi_info in the provider: * check and duplicate provider's info */ int ofi_prov_check_dup_info(const struct util_prov *util_prov, uint32_t api_version, const struct fi_info *user_info, struct fi_info **info) { const struct fi_info *prov_info = util_prov->info; const struct fi_provider *prov = util_prov->prov; struct fi_info *fi, *tail; int ret; if (!info) return -FI_EINVAL; *info = tail = NULL; for ( ; prov_info; prov_info = prov_info->next) { ret = ofi_check_info(util_prov, prov_info, api_version, user_info); if (ret) continue; if (!(fi = fi_dupinfo(prov_info))) { ret = -FI_ENOMEM; goto err; } if (!*info) *info = fi; else tail->next = fi; tail = fi; } return (!*info ? -FI_ENODATA : FI_SUCCESS); err: fi_freeinfo(*info); FI_INFO(prov, FI_LOG_CORE, "cannot copy info\n"); return ret; }