⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mca_base_component_find.c

📁 MPI stands for the Message Passing Interface. Written by the MPI Forum (a large committee comprising
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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, &param_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, &param);    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, &params)) {        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 + -