int DEFAULT_SYMVER_PRE(fi_fabric)(struct fi_fabric_attr *attr, struct fid_fabric **fabric, void *context) { struct fi_prov *prov; if (!attr || !attr->prov_name || !attr->name) return -FI_EINVAL; if (!init) fi_ini(); prov = fi_getprov(attr->prov_name); if (!prov || !prov->provider->fabric) return -FI_ENODEV; return prov->provider->fabric(attr, fabric, context); }
static int fi_register_provider(struct fi_provider *provider, void *dlhandle) { struct fi_prov_context *ctx; struct fi_prov *prov; int ret; if (!provider) { ret = -FI_EINVAL; goto cleanup; } FI_INFO(&core_prov, FI_LOG_CORE, "registering provider: %s (%d.%d)\n", provider->name, FI_MAJOR(provider->version), FI_MINOR(provider->version)); /* The current core implementation is not backward compatible * with providers that support a release earlier than v1.3. * See commit 0f4b6651. */ if (provider->fi_version < FI_VERSION(1, 3)) { FI_INFO(&core_prov, FI_LOG_CORE, "provider has unsupported FI version " "(provider %d.%d != libfabric %d.%d); ignoring\n", FI_MAJOR(provider->fi_version), FI_MINOR(provider->fi_version), FI_MAJOR_VERSION, FI_MINOR_VERSION); ret = -FI_ENOSYS; goto cleanup; } if (fi_apply_filter(&prov_filter, provider->name)) { FI_INFO(&core_prov, FI_LOG_CORE, "\"%s\" filtered by provider include/exclude list, skipping\n", provider->name); ret = -FI_ENODEV; goto cleanup; } if (fi_apply_filter(&prov_log_filter, provider->name)) { ctx = (struct fi_prov_context *) &provider->context; ctx->disable_logging = 1; } prov = fi_getprov(provider->name); if (prov) { /* If this provider is older than an already-loaded * provider of the same name, then discard this one. */ if (FI_VERSION_GE(prov->provider->version, provider->version)) { FI_INFO(&core_prov, FI_LOG_CORE, "a newer %s provider was already loaded; " "ignoring this one\n", provider->name); ret = -FI_EALREADY; goto cleanup; } /* This provider is newer than an already-loaded * provider of the same name, so discard the * already-loaded one. */ FI_INFO(&core_prov, FI_LOG_CORE, "an older %s provider was already loaded; " "keeping this one and ignoring the older one\n", provider->name); cleanup_provider(prov->provider, prov->dlhandle); prov->dlhandle = dlhandle; prov->provider = provider; return 0; } prov = calloc(sizeof *prov, 1); if (!prov) { ret = -FI_ENOMEM; goto cleanup; } prov->dlhandle = dlhandle; prov->provider = provider; if (prov_tail) prov_tail->next = prov; else prov_head = prov; prov_tail = prov; return 0; cleanup: cleanup_provider(provider, dlhandle); return ret; }