static void __attribute__((destructor)) fi_fini(void) { struct fi_prov *prov; if (!init) return; while (prov_head) { prov = prov_head; prov_head = prov->next; cleanup_provider(prov->provider, prov->dlhandle); free(prov); } fi_free_filter(&prov_filter); fi_log_fini(); fi_param_fini(); fi_util_fini(); ofi_osd_fini(); }
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; }
static int ofi_register_provider(struct fi_provider *provider, void *dlhandle) { struct fi_prov_context *ctx; struct ofi_prov *prov = NULL; int ret; if (!provider || !provider->name) { FI_WARN(&core_prov, FI_LOG_CORE, "no provider structure or name\n"); 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)); if (!provider->getinfo || !provider->fabric) { FI_WARN(&core_prov, FI_LOG_CORE, "provider missing mandatory entry points\n"); ret = -FI_EINVAL; goto cleanup; } /* 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; } ctx = (struct fi_prov_context *) &provider->context; ctx->is_util_prov = ofi_has_util_prefix(provider->name); if (ofi_getinfo_filter(provider)) { FI_INFO(&core_prov, FI_LOG_CORE, "\"%s\" filtered by provider include/exclude " "list, skipping\n", provider->name); ret = -FI_ENODEV; goto cleanup; } if (ofi_apply_filter(&prov_log_filter, provider->name)) ctx->disable_logging = 1; prov = ofi_getprov(provider->name, strlen(provider->name)); if (prov) { /* If this provider has not been init yet, then we add the * provider and dlhandle to the struct and exit. */ if (prov->provider == NULL) goto update_prov_registry; /* 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); } else { prov = ofi_create_prov_entry(provider->name); if (!prov) { ret = -FI_EOTHER; goto cleanup; } } update_prov_registry: prov->dlhandle = dlhandle; prov->provider = provider; return 0; cleanup: cleanup_provider(provider, dlhandle); return ret; }