/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality because we * need to look at companion .ompi_info files in the same directory as * the library to generate dependencies, etc. */ static void find_dyn_components(const char *path, pmix_mca_base_framework_t *framework, const char **names, bool include_mode) { pmix_mca_base_component_repository_item_t *ri; pmix_list_t *dy_components; int ret; pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, framework->framework_output, "mca: base: find_dyn_components: checking %s for %s components", path, framework->framework_name); if (NULL != path) { ret = pmix_mca_base_component_repository_add(path); if (PMIX_SUCCESS != ret) { return; } } ret = pmix_mca_base_component_repository_get_components(framework, &dy_components); if (PMIX_SUCCESS != ret) { return; } /* Iterate through the repository and find components that can be included */ PMIX_LIST_FOREACH(ri, dy_components, pmix_mca_base_component_repository_item_t) { if (use_component(include_mode, names, ri->ri_name)) { pmix_mca_base_component_repository_open(framework, ri); } } }
/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality (vs. ltdl's * lt_dladdsearchdir() functionality) because we need to look at * companion .ompi_info files in the same directory as the library to * generate dependencies, etc. If we use the plain lt_dlopen() * functionality, we would not get the directory name of the file * finally opened in recursive dependency traversals. */ static void find_dyn_components(const char *path, const char *type_name, const char **names, bool include_mode, opal_list_t *found_components) { int i, len; char *path_to_use = NULL, *dir, *end; component_file_item_t *file; opal_list_item_t *cur; char prefix[32 + MCA_BASE_MAX_TYPE_NAME_LEN], *basename; /* If path is NULL, iterate over the set of directories specified by the MCA param mca_base_component_path. If path is not NULL, then use that as the path. */ if (NULL == path) { if (NULL != mca_base_component_path) { path_to_use = strdup (mca_base_component_path); } else { /* If there's no path, then there's nothing to search -- we're done */ return; } if (NULL == path_to_use) { /* out of memory */ return; } } else { path_to_use = strdup(path); } /* If we haven't done so already, iterate over all the files in the directories in the path and make a master array of all the matching filenames that we find. Save the filenames in an argv-style array. Re-scan do this if the mca_component_path has changed. */ if (NULL == found_filenames || (NULL != last_path_to_use && 0 != strcmp(path_to_use, last_path_to_use))) { if (NULL != found_filenames) { opal_argv_free(found_filenames); found_filenames = NULL; free(last_path_to_use); last_path_to_use = NULL; } if (NULL == last_path_to_use) { last_path_to_use = strdup(path_to_use); } dir = path_to_use; if (NULL != dir) { do { end = strchr(dir, OPAL_ENV_SEP); if (NULL != end) { *end = '\0'; } if ((0 == strcmp(dir, "USER_DEFAULT") || 0 == strcmp(dir, "USR_DEFAULT")) && NULL != mca_base_user_default_path) { if (0 != lt_dlforeachfile(mca_base_user_default_path, save_filename, NULL)) { break; } } else if (0 == strcmp(dir, "SYS_DEFAULT") || 0 == strcmp(dir, "SYSTEM_DEFAULT")) { if (0 != lt_dlforeachfile(mca_base_system_default_path, save_filename, NULL)) { break; } } else { if (0 != lt_dlforeachfile(dir, save_filename, NULL)) { break; } } dir = end + 1; } while (NULL != end); } } /* Look through the list of found files and find those that match the desired framework name */ snprintf(prefix, sizeof(prefix) - 1, component_template, type_name); len = strlen(prefix); OBJ_CONSTRUCT(&found_files, opal_list_t); for (i = 0; NULL != found_filenames && NULL != found_filenames[i]; ++i) { basename = strrchr(found_filenames[i], '/'); if (NULL == basename) { basename = found_filenames[i]; } else { basename += 1; } if (0 != strncmp(basename, prefix, len)) { continue; } /* We found a match; save all the relevant details in the found_files list */ file = OBJ_NEW(component_file_item_t); if (NULL == file) { return; } strncpy(file->type, type_name, MCA_BASE_MAX_TYPE_NAME_LEN); file->type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; strncpy(file->name, basename + len, MCA_BASE_MAX_COMPONENT_NAME_LEN); file->name[MCA_BASE_MAX_COMPONENT_NAME_LEN] = '\0'; strncpy(file->basename, basename, OPAL_PATH_MAX); file->basename[OPAL_PATH_MAX] = '\0'; strncpy(file->filename, found_filenames[i], OPAL_PATH_MAX); file->filename[OPAL_PATH_MAX] = '\0'; file->status = UNVISITED; opal_list_append(&found_files, (opal_list_item_t *) file); } /* Iterate through all the filenames that we found that matched the framework we were looking for. Since one component may [try to] call another to be loaded, only try to load the UNVISITED files. Also, ignore the return code -- basically, give every file one chance to try to load. If they load, great. If not, great. */ for (cur = opal_list_get_first(&found_files); opal_list_get_end(&found_files) != cur; cur = opal_list_get_next(cur)) { file = (component_file_item_t *) cur; if( UNVISITED == file->status ) { bool op = true; file->status = CHECKING_CYCLE; op = use_component(include_mode, names, file->name); if( true == op ) { open_component(file, found_components); } } } /* So now we have a final list of loaded components. We can free all the file information. */ for (cur = opal_list_remove_first(&found_files); NULL != cur; cur = opal_list_remove_first(&found_files)) { OBJ_RELEASE(cur); } OBJ_DESTRUCT(&found_files); /* All done, now let's cleanup */ free(path_to_use); }
int mca_base_components_filter (const char *framework_name, opal_list_t *components, int output_id, const char *filter_names, uint32_t filter_flags) { mca_base_component_list_item_t *cli, *next; char **requested_component_names = NULL; bool include_mode, can_use; int ret; assert (NULL != components); if (0 == filter_flags && NULL == filter_names) { return OPAL_SUCCESS; } ret = mca_base_component_parse_requested (filter_names, &include_mode, &requested_component_names); if (OPAL_SUCCESS != ret) { return ret; } OPAL_LIST_FOREACH_SAFE(cli, next, components, mca_base_component_list_item_t) { const mca_base_component_t *component = cli->cli_component; mca_base_open_only_dummy_component_t *dummy = (mca_base_open_only_dummy_component_t *) cli->cli_component; can_use = use_component (include_mode, (const char **) requested_component_names, cli->cli_component->mca_component_name); if (!can_use || (filter_flags & dummy->data.param_field) != filter_flags) { if (can_use && (filter_flags & MCA_BASE_METADATA_PARAM_CHECKPOINT) && !(MCA_BASE_METADATA_PARAM_CHECKPOINT & dummy->data.param_field)) { opal_output_verbose(10, output_id, "mca: base: components_filter: " "(%s) Component %s is *NOT* Checkpointable - Disabled", component->reserved, component->mca_component_name); } opal_list_remove_item (components, &cli->super); mca_base_component_unload (component, output_id); OBJ_RELEASE(cli); } else if (filter_flags & MCA_BASE_METADATA_PARAM_CHECKPOINT) { opal_output_verbose(10, output_id, "mca: base: components_filter: " "(%s) Component %s is Checkpointable", component->reserved, component->mca_component_name); } } if (include_mode) { ret = component_find_check (framework_name, requested_component_names, components); } else { ret = OPAL_SUCCESS; } if (NULL != requested_component_names) { opal_argv_free (requested_component_names); } return ret; }
/* * Function to find as many components of a given type as possible. This * includes statically-linked in components as well as opening up a * directory and looking for shared-library MCA components of the * appropriate type (load them if available). * * Return one consolidated array of (mca_base_component_t*) pointing to all * available components. */ int mca_base_component_find(const char *directory, const char *type, const mca_base_component_t *static_components[], const char *requested_components, opal_list_t *found_components, bool open_dso_components) { char **requested_component_names = NULL; mca_base_component_list_item_t *cli; bool include_mode; int i, ret; ret = mca_base_component_parse_requested (requested_components, &include_mode, &requested_component_names); if (OPAL_SUCCESS != ret) { return ret; } /* Find all the components that were statically linked in */ OBJ_CONSTRUCT(found_components, opal_list_t); for (i = 0; NULL != static_components && NULL != static_components[i]; ++i) { if ( use_component(include_mode, (const char**)requested_component_names, static_components[i]->mca_component_name) ) { cli = OBJ_NEW(mca_base_component_list_item_t); if (NULL == cli) { ret = OPAL_ERR_OUT_OF_RESOURCE; goto component_find_out; } cli->cli_component = static_components[i]; opal_list_append(found_components, (opal_list_item_t *) cli); } } #if OPAL_WANT_LIBLTDL /* Find any available dynamic components in the specified directory */ if (open_dso_components && !mca_base_component_disable_dlopen) { find_dyn_components(directory, type, (const char**)requested_component_names, include_mode, found_components); } else { opal_output_verbose(40, 0, "mca: base: component_find: dso loading for %s MCA components disabled", type); } #endif if (include_mode) { ret = component_find_check (type, requested_component_names, found_components); } else { ret = OPAL_SUCCESS; } ret = OPAL_SUCCESS; component_find_out: if (NULL != requested_component_names) { opal_argv_free(requested_component_names); } /* All done */ return ret; }
/* * Function to find as many components of a given type as possible. This * includes statically-linked in components as well as opening up a * directory and looking for shared-library MCA components of the * appropriate type (load them if available). * * Return one consolidated array of (pmix_mca_base_component_t*) pointing to all * available components. */ int pmix_mca_base_component_find (const char *directory, pmix_mca_base_framework_t *framework, bool ignore_requested, bool open_dso_components) { const pmix_mca_base_component_t **static_components = framework->framework_static_components; char **requested_component_names = NULL; pmix_mca_base_component_list_item_t *cli; bool include_mode = true; int ret; pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_COMPONENT, framework->framework_output, "mca: base: component_find: searching %s for %s components", directory, framework->framework_name); if (!ignore_requested) { ret = pmix_mca_base_component_parse_requested (framework->framework_selection, &include_mode, &requested_component_names); if (PMIX_SUCCESS != ret) { return ret; } } /* Find all the components that were statically linked in */ if (static_components) { for (int i = 0 ; NULL != static_components[i]; ++i) { if ( use_component(include_mode, (const char**)requested_component_names, static_components[i]->pmix_mca_component_name) ) { cli = PMIX_NEW(pmix_mca_base_component_list_item_t); if (NULL == cli) { ret = PMIX_ERR_OUT_OF_RESOURCE; goto component_find_out; } cli->cli_component = static_components[i]; pmix_list_append(&framework->framework_components, (pmix_list_item_t *) cli); } } } #if PMIX_HAVE_PDL_SUPPORT /* Find any available dynamic components in the specified directory */ if (open_dso_components && !pmix_mca_base_component_disable_dlopen) { find_dyn_components(directory, framework, (const char**)requested_component_names, include_mode); } else { pmix_output_verbose (PMIX_MCA_BASE_VERBOSE_INFO, 0, "pmix:mca: base: component_find: dso loading for %s MCA components disabled", framework->framework_name); } #endif if (include_mode) { ret = component_find_check (framework, requested_component_names); } else { ret = PMIX_SUCCESS; } component_find_out: if (NULL != requested_component_names) { pmix_argv_free(requested_component_names); } /* All done */ return ret; }
int pmix_mca_base_components_filter (pmix_mca_base_framework_t *framework, uint32_t filter_flags) { pmix_list_t *components = &framework->framework_components; int output_id = framework->framework_output; pmix_mca_base_component_list_item_t *cli, *next; char **requested_component_names = NULL; bool include_mode, can_use; int ret; assert (NULL != components); if (0 == filter_flags && NULL == framework->framework_selection) { return PMIX_SUCCESS; } ret = pmix_mca_base_component_parse_requested (framework->framework_selection, &include_mode, &requested_component_names); if (PMIX_SUCCESS != ret) { return ret; } PMIX_LIST_FOREACH_SAFE(cli, next, components, pmix_mca_base_component_list_item_t) { const pmix_mca_base_component_t *component = cli->cli_component; pmix_mca_base_open_only_dummy_component_t *dummy = (pmix_mca_base_open_only_dummy_component_t *) cli->cli_component; can_use = use_component(include_mode, (const char **) requested_component_names, cli->cli_component->pmix_mca_component_name); if (!can_use || (filter_flags & dummy->data.param_field) != filter_flags) { if (can_use && (filter_flags & PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT) && !(PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT & dummy->data.param_field)) { pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, "pmix:mca: base: components_filter: " "(%s) Component %s is *NOT* Checkpointable - Disabled", component->reserved, component->pmix_mca_component_name); } pmix_list_remove_item(components, &cli->super); pmix_mca_base_component_unload(component, output_id); PMIX_RELEASE(cli); } else if (filter_flags & PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT) { pmix_output_verbose(PMIX_MCA_BASE_VERBOSE_COMPONENT, output_id, "pmix:mca: base: components_filter: " "(%s) Component %s is Checkpointable", component->reserved, component->pmix_mca_component_name); } } if (include_mode) { ret = component_find_check(framework, requested_component_names); } else { ret = PMIX_SUCCESS; } if (NULL != requested_component_names) { pmix_argv_free(requested_component_names); } return ret; }
/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality (vs. ltdl's * lt_dladdsearchdir() functionality) because we need to look at * companion .ompi_info files in the same directory as the library to * generate dependencies, etc. If we use the plain lt_dlopen() * functionality, we would not get the directory name of the file * finally opened in recursive dependency traversals. */ static void find_dyn_components(const char *path, const char *type_name, const char **name, bool include_mode, opal_list_t *found_components) { ltfn_data_holder_t params; char *path_to_use, *dir, *end; component_file_item_t *file; opal_list_item_t *cur; strncpy(params.type, type_name, MCA_BASE_MAX_TYPE_NAME_LEN); params.type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; params.name[0] = '\0'; /* If path is NULL, iterate over the set of directories specified by the MCA param mca_base_component_path. If path is not NULL, then use that as the path. */ if (NULL == path) { mca_base_param_lookup_string(mca_base_param_component_path, &path_to_use); if (NULL == path_to_use) { /* If there's no path, then there's nothing to search -- we're done */ return; } } else { path_to_use = strdup(path); } /* Iterate over all the files in the directories in the path and make a master array of all the matching filenames that we find. */ OBJ_CONSTRUCT(&found_files, opal_list_t); dir = path_to_use; if (NULL != dir) { do { end = strchr(dir, OPAL_ENV_SEP); if (NULL != end) { *end = '\0'; } if (0 != lt_dlforeachfile(dir, save_filename, ¶ms)) { break; } dir = end + 1; } while (NULL != end); } /* Iterate through all the filenames that we found. Since one component may [try to] call another to be loaded, only try to load the UNVISITED files. Also, ignore the return code -- basically, give every file one chance to try to load. If they load, great. If not, great. */ for (cur = opal_list_get_first(&found_files); opal_list_get_end(&found_files) != cur; cur = opal_list_get_next(cur)) { file = (component_file_item_t *) cur; if( UNVISITED == file->status ) { bool op = true; file->status = CHECKING_CYCLE; op = use_component(include_mode, name, file->name); if( true == op ) { open_component(file, found_components); } } } /* So now we have a final list of loaded components. We can free all the file information. */ for (cur = opal_list_remove_first(&found_files); NULL != cur; cur = opal_list_remove_first(&found_files)) { OBJ_RELEASE(cur); } /* All done, now let's cleanup */ free(path_to_use); OBJ_DESTRUCT(&found_files); }
/* * Function to find as many components of a given type as possible. This * includes statically-linked in components as well as opening up a * directory and looking for shared-library MCA components of the * appropriate type (load them if available). * * Return one consolidated array of (mca_base_component_t*) pointing to all * available components. */ int mca_base_component_find(const char *directory, const char *type, const mca_base_component_t *static_components[], char **requested_component_names, bool include_mode, opal_list_t *found_components, bool open_dso_components) { int i; opal_list_item_t *item; mca_base_component_list_item_t *cli; /* Find all the components that were statically linked in */ OBJ_CONSTRUCT(found_components, opal_list_t); for (i = 0; NULL != static_components[i]; ++i) { if ( use_component(include_mode, (const char**)requested_component_names, static_components[i]->mca_component_name) ) { cli = OBJ_NEW(mca_base_component_list_item_t); if (NULL == cli) { return OPAL_ERR_OUT_OF_RESOURCE; } cli->cli_component = static_components[i]; opal_list_append(found_components, (opal_list_item_t *) cli); } } #if OMPI_WANT_LIBLTDL /* Find any available dynamic components in the specified directory */ if (open_dso_components) { int param, param_disable_dlopen; param = mca_base_param_find("mca", NULL, "component_disable_dlopen"); mca_base_param_lookup_int(param, ¶m_disable_dlopen); if (0 == param_disable_dlopen) { find_dyn_components(directory, type, (const char**)requested_component_names, include_mode, found_components); } } else { opal_output_verbose(40, 0, "mca: base: component_find: dso loading for %s MCA components disabled", type); } #endif /* Ensure that *all* requested components exist. Print a warning and abort if they do not. */ for (i = 0; include_mode && NULL != requested_component_names && NULL != requested_component_names[i]; ++i) { for (item = opal_list_get_first(found_components); opal_list_get_end(found_components) != item; item = opal_list_get_next(item)) { cli = (mca_base_component_list_item_t*) item; if (0 == strcmp(requested_component_names[i], cli->cli_component->mca_component_name)) { break; } } if (opal_list_get_end(found_components) == item) { char h[MAXHOSTNAMELEN]; gethostname(h, sizeof(h)); opal_show_help("help-mca-base.txt", "find-available:not-valid", true, h, type, requested_component_names[i]); return OPAL_ERR_NOT_FOUND; } } /* All done */ return OPAL_SUCCESS; }