1
1

Fixes trac:1271: make the OPAL MCA base read the list of MCA DSO filenames

''once'' and keep the names in an argv-style array.  Each time we go
to open a framework, we just scan that array rather than re-reading
all the filenames from the filesystem.

This commit was SVN r20309.

The following Trac tickets were found above:
  Ticket 1271 --> https://svn.open-mpi.org/trac/ompi/ticket/1271
Этот коммит содержится в:
Jeff Squyres 2009-01-21 22:27:05 +00:00
родитель 084de9e245
Коммит 58a25cae69
3 изменённых файлов: 94 добавлений и 102 удалений

Просмотреть файл

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -128,6 +129,11 @@ OPAL_DECLSPEC int mca_base_component_find(const char *directory, const char *typ
opal_list_t *found_components, opal_list_t *found_components,
bool open_dso_components); bool open_dso_components);
/* Safely release some memory allocated by mca_base_component_find()
(i.e., is safe to call even if you never called
mca_base_component_find()). */
OPAL_DECLSPEC int mca_base_component_find_finalize(void);
/* mca_base_components_open.c */ /* mca_base_components_open.c */
OPAL_DECLSPEC int mca_base_components_open(const char *type_name, int output_id, OPAL_DECLSPEC int mca_base_components_open(const char *type_name, int output_id,

Просмотреть файл

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -33,9 +34,13 @@ int mca_base_close(void)
if (mca_base_opened) { if (mca_base_opened) {
/* Close down the component repository */ /* Close down the component repository */
mca_base_component_repository_finalize(); mca_base_component_repository_finalize();
opal_output_close (0);
/* Shut down the dynamic component finder */
mca_base_component_find_finalize();
/* Close opal output stream 0 */
opal_output_close(0);
} }
mca_base_opened = false; mca_base_opened = false;

Просмотреть файл

@ -39,6 +39,7 @@
#endif #endif
#include "opal/util/output.h" #include "opal/util/output.h"
#include "opal/util/argv.h"
#include "opal/util/show_help.h" #include "opal/util/show_help.h"
#include "opal/class/opal_list.h" #include "opal/class/opal_list.h"
#include "opal/mca/mca.h" #include "opal/mca/mca.h"
@ -82,12 +83,6 @@ typedef struct dependency_item_t dependency_item_t;
static OBJ_CLASS_INSTANCE(dependency_item_t, opal_list_item_t, NULL, NULL); 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 + 1];
char name[MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
};
typedef struct ltfn_data_holder_t ltfn_data_holder_t;
#if OPAL_HAVE_LTDL_ADVISE #if OPAL_HAVE_LTDL_ADVISE
extern lt_dladvise opal_mca_dladvise; extern lt_dladvise opal_mca_dladvise;
#endif #endif
@ -99,7 +94,7 @@ extern lt_dladvise opal_mca_dladvise;
* Private functions * Private functions
*/ */
static void find_dyn_components(const char *path, const char *type, static void find_dyn_components(const char *path, const char *type,
const char **name, bool include_mode, const char **names, bool include_mode,
opal_list_t *found_components); opal_list_t *found_components);
static int save_filename(const char *filename, lt_ptr data); static int save_filename(const char *filename, lt_ptr data);
static int open_component(component_file_item_t *target_file, static int open_component(component_file_item_t *target_file,
@ -119,6 +114,7 @@ static const char *ompi_info_suffix = ".ompi_info";
static const char *key_dependency = "dependency="; static const char *key_dependency = "dependency=";
static const char component_template[] = "mca_%s_"; static const char component_template[] = "mca_%s_";
static opal_list_t found_files; static opal_list_t found_files;
static char **found_filenames = NULL;
#endif /* OMPI_WANT_LIBLTDL */ #endif /* OMPI_WANT_LIBLTDL */
static bool use_component(const bool include_mode, static bool use_component(const bool include_mode,
@ -209,6 +205,15 @@ int mca_base_component_find(const char *directory, const char *type,
return OPAL_SUCCESS; return OPAL_SUCCESS;
} }
int mca_base_component_find_finalize(void)
{
if (NULL != found_filenames) {
opal_argv_free(found_filenames);
found_filenames = NULL;
}
return OPAL_SUCCESS;
}
#if OMPI_WANT_LIBLTDL #if OMPI_WANT_LIBLTDL
/* /*
@ -223,25 +228,22 @@ int mca_base_component_find(const char *directory, const char *type,
* finally opened in recursive dependency traversals. * finally opened in recursive dependency traversals.
*/ */
static void find_dyn_components(const char *path, const char *type_name, static void find_dyn_components(const char *path, const char *type_name,
const char **name, bool include_mode, const char **names, bool include_mode,
opal_list_t *found_components) opal_list_t *found_components)
{ {
ltfn_data_holder_t params; int i, len;
char *path_to_use, *dir, *end; char *path_to_use, *dir, *end;
component_file_item_t *file; component_file_item_t *file;
opal_list_item_t *cur; opal_list_item_t *cur;
char prefix[32 + MCA_BASE_MAX_TYPE_NAME_LEN], *basename;
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 /* 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 the MCA param mca_base_component_path. If path is not NULL, then
use that as the path. */ use that as the path. */
if (NULL == path) { if (NULL == path) {
mca_base_param_lookup_string(mca_base_param_component_path, &path_to_use); mca_base_param_lookup_string(mca_base_param_component_path,
&path_to_use);
if (NULL == path_to_use) { if (NULL == path_to_use) {
/* If there's no path, then there's nothing to search -- we're /* If there's no path, then there's nothing to search -- we're
done */ done */
@ -251,31 +253,68 @@ static void find_dyn_components(const char *path, const char *type_name,
path_to_use = strdup(path); path_to_use = strdup(path);
} }
/* Iterate over all the files in the directories in the path and /* If we haven't done so already, iterate over all the files in
make a master array of all the matching filenames that we the directories in the path and make a master array of all the
find. */ matching filenames that we find. Save the filenames in an
argv-style array. */
OBJ_CONSTRUCT(&found_files, opal_list_t); if (NULL == found_filenames) {
dir = path_to_use; dir = path_to_use;
if (NULL != dir) { if (NULL != dir) {
do { do {
end = strchr(dir, OPAL_ENV_SEP); end = strchr(dir, OPAL_ENV_SEP);
if (NULL != end) { if (NULL != end) {
*end = '\0'; *end = '\0';
} }
if (0 != lt_dlforeachfile(dir, save_filename, &params)) { if (0 != lt_dlforeachfile(dir, save_filename, NULL)) {
break; break;
} }
dir = end + 1; dir = end + 1;
} while (NULL != end); } while (NULL != end);
}
} }
/* Iterate through all the filenames that we found. Since one /* Look through the list of found files and find those that match
component may [try to] call another to be loaded, only try to load the desired framework name */
the UNVISITED files. Also, ignore the return code -- basically, snprintf(prefix, sizeof(prefix) - 1, component_template, type_name);
give every file one chance to try to load. If they load, great. len = strlen(prefix);
If not, great. */ 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, OMPI_PATH_MAX);
file->basename[OMPI_PATH_MAX] = '\0';
strncpy(file->filename, found_filenames[i], OMPI_PATH_MAX);
file->filename[OMPI_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); for (cur = opal_list_get_first(&found_files);
opal_list_get_end(&found_files) != cur; opal_list_get_end(&found_files) != cur;
cur = opal_list_get_next(cur)) { cur = opal_list_get_next(cur)) {
@ -285,93 +324,35 @@ static void find_dyn_components(const char *path, const char *type_name,
bool op = true; bool op = true;
file->status = CHECKING_CYCLE; file->status = CHECKING_CYCLE;
op = use_component(include_mode, name, file->name); op = use_component(include_mode, names, file->name);
if( true == op ) { if( true == op ) {
open_component(file, found_components); open_component(file, found_components);
} }
} }
} }
/* So now we have a final list of loaded components. We can free all /* So now we have a final list of loaded components. We can free all
the file information. */ the file information. */
for (cur = opal_list_remove_first(&found_files); for (cur = opal_list_remove_first(&found_files);
NULL != cur; NULL != cur;
cur = opal_list_remove_first(&found_files)) { cur = opal_list_remove_first(&found_files)) {
OBJ_RELEASE(cur); OBJ_RELEASE(cur);
} }
OBJ_DESTRUCT(&found_files);
/* All done, now let's cleanup */ /* All done, now let's cleanup */
free(path_to_use); free(path_to_use);
OBJ_DESTRUCT(&found_files);
} }
/* /*
* Given a filename, see if it appears to be of the proper filename * Blindly save all filenames into an argv-style list. This function
* format. If so, save it in the array so that we can process it * is the callback from lt_dlforeachfile().
* later.
*/ */
static int save_filename(const char *filename, lt_ptr data) static int save_filename(const char *filename, lt_ptr data)
{ {
size_t len, prefix_len, total_len; opal_argv_append_nosize(&found_filenames, filename);
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 ( 0 < strlen(params->name) ) {
len += strlen(params->name);
}
prefix = (char*)malloc(len);
snprintf(prefix, len, component_template, params->type);
prefix_len = strlen(prefix);
if (0 < strlen(params->name)) {
strncat(prefix, params->name, len - prefix_len);
}
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; 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) {
free(prefix);
return OPAL_ERR_OUT_OF_RESOURCE;
}
strncpy(component_file->type, params->type, MCA_BASE_MAX_TYPE_NAME_LEN);
component_file->type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
strncpy(component_file->name, basename + prefix_len,
MCA_BASE_MAX_COMPONENT_NAME_LEN);
component_file->name[MCA_BASE_MAX_COMPONENT_NAME_LEN] = '\0';
strncpy(component_file->basename, basename, OMPI_PATH_MAX);
component_file->basename[OMPI_PATH_MAX] = '\0';
strncpy(component_file->filename, filename, OMPI_PATH_MAX);
component_file->filename[OMPI_PATH_MAX] = '\0';
component_file->status = UNVISITED;
opal_list_append(&found_files, (opal_list_item_t *) component_file);
/* All done */
free(prefix);
return 0;
} }