📄 mca_base_component_find.c
字号:
/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */#include "opal_config.h"#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdlib.h>#if OMPI_WANT_LIBLTDL#include "opal/libltdl/ltdl.h"#endif#include "opal/util/output.h"#include "opal/class/opal_list.h"#include "opal/mca/mca.h"#include "opal/mca/base/base.h"#include "opal/mca/base/mca_base_component_repository.h"#include "opal/constants.h"/* * Private types */typedef enum component_status { UNVISITED, FAILED_TO_LOAD, CHECKING_CYCLE, LOADED, STATUS_MAX} component_status_t;struct component_file_item_t { opal_list_item_t super; char type[MCA_BASE_MAX_TYPE_NAME_LEN]; char name[MCA_BASE_MAX_COMPONENT_NAME_LEN]; char basename[OMPI_PATH_MAX]; char filename[OMPI_PATH_MAX]; component_status_t status;};typedef struct component_file_item_t component_file_item_t;static OBJ_CLASS_INSTANCE(component_file_item_t, opal_list_item_t, NULL, NULL);struct dependency_item_t { opal_list_item_t super; component_file_item_t *di_component_file_item;};typedef struct dependency_item_t dependency_item_t;static OBJ_CLASS_INSTANCE(dependency_item_t, opal_list_item_t, NULL, NULL);struct ltfn_data_holder_t { char type[MCA_BASE_MAX_TYPE_NAME_LEN]; char name[MCA_BASE_MAX_COMPONENT_NAME_LEN];};typedef struct ltfn_data_holder_t ltfn_data_holder_t;#if OMPI_WANT_LIBLTDL/* * Private functions */static void find_dyn_components(const char *path, const char *type, const char *name, opal_list_t *found_components);static int save_filename(const char *filename, lt_ptr data);static int open_component(component_file_item_t *target_file, opal_list_t *found_components);static int check_ompi_info(component_file_item_t *target_file, opal_list_t *dependencies, opal_list_t *found_components);static int check_dependency(char *line, component_file_item_t *target_file, opal_list_t *dependencies, opal_list_t *found_components);static void free_dependency_list(opal_list_t *dependencies);/* * Private variables */static const char *ompi_info_suffix = ".ompi_info";static const char *key_dependency = "dependency=";static const char component_template[] = "mca_%s_";static opal_list_t found_files;#endif /* OMPI_WANT_LIBLTDL *//* * 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[], opal_list_t *found_components, bool open_dso_components){ int i; 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) { 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, NULL, found_components); } } else { opal_output_verbose(40, 0, "mca: base: component_find: dso loading for %s MCA components disabled", type); }#endif /* All done */ return OPAL_SUCCESS;}#if OMPI_WANT_LIBLTDL/* * 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, opal_list_t *found_components){ ltfn_data_holder_t params; char *path_to_use, *dir, *end, *param; component_file_item_t *file; opal_list_item_t *cur; strcpy(params.type, type_name); if (NULL == name) { params.name[0] = '\0'; opal_output_verbose(40, 0, "mca: base: component_find: looking for all dynamic %s MCA components", type_name, NULL); } else { strcpy(params.name, name); opal_output_verbose(40, 0, "mca: base: component_find: looking for dynamic %s MCA component named \"%s\"", type_name, name, NULL); } /* 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. */ param = NULL; if (NULL == path) { mca_base_param_lookup_string(mca_base_param_component_path, ¶m); if (NULL == param) { /* If there's no path, then there's nothing to search -- we're done */ return; } else { path_to_use = strdup(param); } } 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) { 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 */ if (NULL != param) { free(param); } if (NULL != path_to_use) { free(path_to_use); } OBJ_DESTRUCT(&found_files);}/* * Given a filename, see if it appears to be of the proper filename * format. If so, save it in the array so that we can process it * later. */static int save_filename(const char *filename, lt_ptr data){ size_t len, prefix_len, total_len; char *prefix; const char *basename; component_file_item_t *component_file; ltfn_data_holder_t *params = (ltfn_data_holder_t *) data; /* Check to see if the file is named what we expect it to be named */ len = sizeof(component_template) + strlen(params->type) + 32; if (NULL != params->name) { len += strlen(params->name); } prefix = (char*)malloc(len); snprintf(prefix, len, component_template, params->type); prefix_len = strlen(prefix); if (NULL != params->name) { strcat(prefix, params->name); } total_len = strlen(prefix); basename = strrchr(filename, '/'); if (NULL == basename) { basename = filename; } else { basename += 1; } if (0 != strncmp(basename, prefix, total_len)) { free(prefix); return 0; } /* Save all the info and put it in the list of found components */ component_file = OBJ_NEW(component_file_item_t); if (NULL == component_file) { return OPAL_ERR_OUT_OF_RESOURCE; } strcpy(component_file->type, params->type); strcpy(component_file->name, basename + prefix_len); strcpy(component_file->basename, basename); strcpy(component_file->filename, filename); component_file->status = UNVISITED; opal_list_append(&found_files, (opal_list_item_t *) component_file); /* All done */ free(prefix); return 0;}/* * Open a component, chasing down its dependencies first, if possible. */static int open_component(component_file_item_t *target_file, opal_list_t *found_components){ int show_errors, param; lt_dlhandle component_handle; mca_base_component_t *component_struct; char *struct_name, *err; opal_list_t dependencies; opal_list_item_t *cur; mca_base_component_list_item_t *mitem; dependency_item_t *ditem; size_t len; opal_output_verbose(40, 0, "mca: base: component_find: examining dyanmic %s MCA component \"%s\"", target_file->type, target_file->name, NULL); opal_output_verbose(40, 0, "mca: base: component_find: %s", target_file->filename, NULL); param = mca_base_param_find("mca", NULL, "component_show_load_errors"); mca_base_param_lookup_int(param, &show_errors); /* Was this component already loaded (e.g., via dependency)? */ if (LOADED == target_file->status) { opal_output_verbose(40, 0, "mca: base: component_find: already loaded (ignored)", NULL); return OPAL_SUCCESS; } /* Ensure that this component is not already loaded (should only happen if it was statically loaded). It's an error if it's already loaded because we're evaluating this file -- not this component.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -