Merge pull request #516 from hjelmn/repository_update
RFC: Repository update
Этот коммит содержится в:
Коммит
e794658f2d
@ -145,11 +145,8 @@ OPAL_DECLSPEC char * mca_base_component_to_string(const mca_base_component_t *a)
|
|||||||
|
|
||||||
/* mca_base_component_find.c */
|
/* mca_base_component_find.c */
|
||||||
|
|
||||||
OPAL_DECLSPEC int mca_base_component_find(const char *directory, const char *type,
|
OPAL_DECLSPEC int mca_base_component_find (const char *directory, mca_base_framework_t *framework,
|
||||||
const mca_base_component_t *static_components[],
|
bool ignore_requested, bool open_dso_components);
|
||||||
const char *requested_components,
|
|
||||||
opal_list_t *found_components,
|
|
||||||
bool open_dso_components);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the requested component string and return an opal_argv of the requested
|
* Parse the requested component string and return an opal_argv of the requested
|
||||||
@ -176,8 +173,7 @@ int mca_base_component_parse_requested (const char *requested, bool *include_mod
|
|||||||
* This function closes and releases any components that do not match the filter_name and
|
* This function closes and releases any components that do not match the filter_name and
|
||||||
* filter flags.
|
* filter flags.
|
||||||
*/
|
*/
|
||||||
OPAL_DECLSPEC int mca_base_components_filter (const char *framework_name, opal_list_t *components, int output_id,
|
OPAL_DECLSPEC int mca_base_components_filter (mca_base_framework_t *framework, uint32_t filter_flags);
|
||||||
const char *filter_names, uint32_t filter_flags);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,75 +55,16 @@
|
|||||||
#include "opal/constants.h"
|
#include "opal/constants.h"
|
||||||
#include "opal/mca/dl/base/base.h"
|
#include "opal/mca/dl/base/base.h"
|
||||||
|
|
||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
/*
|
|
||||||
* Private types; only necessary when we're dlopening components.
|
|
||||||
*/
|
|
||||||
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 + 1];
|
|
||||||
char name[MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
|
|
||||||
char basename[OPAL_PATH_MAX + 1];
|
|
||||||
char filename[OPAL_PATH_MAX + 1];
|
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
|
||||||
|
|
||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
/*
|
/*
|
||||||
* Private functions
|
* Private functions
|
||||||
*/
|
*/
|
||||||
static void find_dyn_components(const char *path, const char *type,
|
static void find_dyn_components(const char *path, mca_base_framework_t *framework,
|
||||||
const char **names, bool include_mode,
|
const char **names, bool include_mode);
|
||||||
opal_list_t *found_components);
|
|
||||||
static int save_filename(const char *filename, void *data);
|
|
||||||
static int open_component(component_file_item_t *target_file,
|
|
||||||
opal_list_t *found_components);
|
|
||||||
static int check_opal_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 *opal_info_suffix = ".ompi_info";
|
|
||||||
static const char *key_dependency = "dependency=";
|
|
||||||
static const char component_template[] = "mca_%s_";
|
|
||||||
static opal_list_t found_files;
|
|
||||||
static char **found_filenames = NULL;
|
|
||||||
static char *last_path_to_use = NULL;
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
|
||||||
static int component_find_check (const char *framework_name, char **requested_component_names, opal_list_t *components);
|
static int component_find_check (mca_base_framework_t *framework, char **requested_component_names);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dummy structure for casting for open_only logic
|
* Dummy structure for casting for open_only logic
|
||||||
@ -152,27 +93,26 @@ static bool use_component(const bool include_mode,
|
|||||||
* Return one consolidated array of (mca_base_component_t*) pointing to all
|
* Return one consolidated array of (mca_base_component_t*) pointing to all
|
||||||
* available components.
|
* available components.
|
||||||
*/
|
*/
|
||||||
int mca_base_component_find(const char *directory, const char *type,
|
int mca_base_component_find (const char *directory, mca_base_framework_t *framework,
|
||||||
const mca_base_component_t *static_components[],
|
bool ignore_requested, bool open_dso_components)
|
||||||
const char *requested_components,
|
|
||||||
opal_list_t *found_components,
|
|
||||||
bool open_dso_components)
|
|
||||||
{
|
{
|
||||||
|
const mca_base_component_t **static_components = framework->framework_static_components;
|
||||||
char **requested_component_names = NULL;
|
char **requested_component_names = NULL;
|
||||||
mca_base_component_list_item_t *cli;
|
mca_base_component_list_item_t *cli;
|
||||||
bool include_mode;
|
bool include_mode = true;
|
||||||
int i, ret;
|
int ret;
|
||||||
|
|
||||||
ret = mca_base_component_parse_requested (requested_components, &include_mode,
|
if (!ignore_requested) {
|
||||||
|
ret = mca_base_component_parse_requested (framework->framework_selection, &include_mode,
|
||||||
&requested_component_names);
|
&requested_component_names);
|
||||||
if (OPAL_SUCCESS != ret) {
|
if (OPAL_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find all the components that were statically linked in */
|
/* Find all the components that were statically linked in */
|
||||||
OBJ_CONSTRUCT(found_components, opal_list_t);
|
if (static_components) {
|
||||||
for (i = 0; NULL != static_components &&
|
for (int i = 0 ; NULL != static_components[i]; ++i) {
|
||||||
NULL != static_components[i]; ++i) {
|
|
||||||
if ( use_component(include_mode,
|
if ( use_component(include_mode,
|
||||||
(const char**)requested_component_names,
|
(const char**)requested_component_names,
|
||||||
static_components[i]->mca_component_name) ) {
|
static_components[i]->mca_component_name) ) {
|
||||||
@ -182,25 +122,25 @@ int mca_base_component_find(const char *directory, const char *type,
|
|||||||
goto component_find_out;
|
goto component_find_out;
|
||||||
}
|
}
|
||||||
cli->cli_component = static_components[i];
|
cli->cli_component = static_components[i];
|
||||||
opal_list_append(found_components, (opal_list_item_t *) cli);
|
opal_list_append(&framework->framework_components, (opal_list_item_t *) cli);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
/* Find any available dynamic components in the specified directory */
|
/* Find any available dynamic components in the specified directory */
|
||||||
if (open_dso_components && !mca_base_component_disable_dlopen) {
|
if (open_dso_components && !mca_base_component_disable_dlopen) {
|
||||||
find_dyn_components(directory, type,
|
find_dyn_components(directory, framework, (const char**)requested_component_names,
|
||||||
(const char**)requested_component_names,
|
include_mode);
|
||||||
include_mode, found_components);
|
|
||||||
} else {
|
} else {
|
||||||
opal_output_verbose(40, 0,
|
opal_output_verbose(40, 0,
|
||||||
"mca: base: component_find: dso loading for %s MCA components disabled",
|
"mca: base: component_find: dso loading for %s MCA components disabled",
|
||||||
type);
|
framework->framework_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (include_mode) {
|
if (include_mode) {
|
||||||
ret = component_find_check (type, requested_component_names, found_components);
|
ret = component_find_check (framework, requested_component_names);
|
||||||
} else {
|
} else {
|
||||||
ret = OPAL_SUCCESS;
|
ret = OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -218,22 +158,13 @@ component_find_out:
|
|||||||
|
|
||||||
int mca_base_component_find_finalize(void)
|
int mca_base_component_find_finalize(void)
|
||||||
{
|
{
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
if (NULL != found_filenames) {
|
|
||||||
opal_argv_free(found_filenames);
|
|
||||||
found_filenames = NULL;
|
|
||||||
}
|
|
||||||
if (NULL != last_path_to_use) {
|
|
||||||
free(last_path_to_use);
|
|
||||||
last_path_to_use = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mca_base_components_filter (const char *framework_name, opal_list_t *components, int output_id,
|
int mca_base_components_filter (mca_base_framework_t *framework, uint32_t filter_flags)
|
||||||
const char *filter_names, uint32_t filter_flags)
|
|
||||||
{
|
{
|
||||||
|
opal_list_t *components = &framework->framework_components;
|
||||||
|
int output_id = framework->framework_output;
|
||||||
mca_base_component_list_item_t *cli, *next;
|
mca_base_component_list_item_t *cli, *next;
|
||||||
char **requested_component_names = NULL;
|
char **requested_component_names = NULL;
|
||||||
bool include_mode, can_use;
|
bool include_mode, can_use;
|
||||||
@ -241,11 +172,11 @@ int mca_base_components_filter (const char *framework_name, opal_list_t *compone
|
|||||||
|
|
||||||
assert (NULL != components);
|
assert (NULL != components);
|
||||||
|
|
||||||
if (0 == filter_flags && NULL == filter_names) {
|
if (0 == filter_flags && NULL == framework->framework_selection) {
|
||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mca_base_component_parse_requested (filter_names, &include_mode,
|
ret = mca_base_component_parse_requested (framework->framework_selection, &include_mode,
|
||||||
&requested_component_names);
|
&requested_component_names);
|
||||||
if (OPAL_SUCCESS != ret) {
|
if (OPAL_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
@ -284,7 +215,7 @@ int mca_base_components_filter (const char *framework_name, opal_list_t *compone
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (include_mode) {
|
if (include_mode) {
|
||||||
ret = component_find_check (framework_name, requested_component_names, components);
|
ret = component_find_check (framework, requested_component_names);
|
||||||
} else {
|
} else {
|
||||||
ret = OPAL_SUCCESS;
|
ret = OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -306,626 +237,32 @@ int mca_base_components_filter (const char *framework_name, opal_list_t *compone
|
|||||||
* need to look at companion .ompi_info files in the same directory as
|
* need to look at companion .ompi_info files in the same directory as
|
||||||
* the library to generate dependencies, etc.
|
* the library to generate dependencies, etc.
|
||||||
*/
|
*/
|
||||||
static void find_dyn_components(const char *path, const char *type_name,
|
static void find_dyn_components(const char *path, mca_base_framework_t *framework,
|
||||||
const char **names, bool include_mode,
|
const char **names, bool include_mode)
|
||||||
opal_list_t *found_components)
|
|
||||||
{
|
{
|
||||||
int i, len;
|
mca_base_component_repository_item_t *ri;
|
||||||
char *path_to_use = NULL, *dir, *end;
|
opal_list_t *dy_components;
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
path_to_use = strdup(path);
|
|
||||||
}
|
|
||||||
if (NULL == path_to_use) {
|
|
||||||
/* out of memory */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 != opal_dl_foreachfile(mca_base_user_default_path,
|
|
||||||
save_filename, NULL)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (0 == strcmp(dir, "SYS_DEFAULT") ||
|
|
||||||
0 == strcmp(dir, "SYSTEM_DEFAULT")) {
|
|
||||||
if (0 != opal_dl_foreachfile(mca_base_system_default_path,
|
|
||||||
save_filename, NULL)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (0 != opal_dl_foreachfile(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) {
|
|
||||||
free(path_to_use);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Blindly save all filenames into an argv-style list. This function
|
|
||||||
* is the callback from lt_dlforeachfile().
|
|
||||||
*/
|
|
||||||
static int save_filename(const char *filename, void *data)
|
|
||||||
{
|
|
||||||
opal_argv_append_nosize(&found_filenames, filename);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int file_exists(const char *filename, const char *ext)
|
|
||||||
{
|
|
||||||
char *final;
|
|
||||||
struct stat buf;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (NULL != ext) {
|
if (NULL != path) {
|
||||||
asprintf(&final, "%s.%s", filename, ext);
|
ret = mca_base_component_repository_add (path);
|
||||||
} else {
|
if (OPAL_SUCCESS != ret) {
|
||||||
final = strdup(filename);
|
return;
|
||||||
}
|
|
||||||
if (NULL == final) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = stat(final, &buf);
|
|
||||||
free(final);
|
|
||||||
return (0 == ret ? 1 : 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)
|
|
||||||
{
|
|
||||||
opal_dl_handle_t *component_handle;
|
|
||||||
mca_base_component_t *component_struct;
|
|
||||||
char *struct_name;
|
|
||||||
opal_list_t dependencies;
|
|
||||||
opal_list_item_t *cur;
|
|
||||||
mca_base_component_list_item_t *mitem;
|
|
||||||
dependency_item_t *ditem;
|
|
||||||
size_t len;
|
|
||||||
int vl;
|
|
||||||
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: examining dyanmic %s MCA component \"%s\"",
|
|
||||||
target_file->type, target_file->name);
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: %s", target_file->filename);
|
|
||||||
|
|
||||||
vl = mca_base_component_show_load_errors ? 0 : 40;
|
|
||||||
|
|
||||||
/* 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)");
|
|
||||||
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.
|
|
||||||
Hence, returning OPAL_ERR_PARAM indicates that the *file* failed
|
|
||||||
to load, not the component. */
|
|
||||||
|
|
||||||
for (cur = opal_list_get_first(found_components);
|
|
||||||
opal_list_get_end(found_components) != cur;
|
|
||||||
cur = opal_list_get_next(cur)) {
|
|
||||||
mitem = (mca_base_component_list_item_t *) cur;
|
|
||||||
if (0 == strcmp(mitem->cli_component->mca_type_name, target_file->type) &&
|
|
||||||
0 == strcmp(mitem->cli_component->mca_component_name, target_file->name)) {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: already loaded (ignored)");
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look at see if this component has any dependencies. If so, load
|
ret = mca_base_component_repository_get_components (framework, &dy_components);
|
||||||
them. If we can't load them, then this component must also fail to
|
if (OPAL_SUCCESS != ret) {
|
||||||
load. */
|
return;
|
||||||
|
|
||||||
OBJ_CONSTRUCT(&dependencies, opal_list_t);
|
|
||||||
if (0 != check_opal_info(target_file, &dependencies, found_components)) {
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now try to load the component */
|
/* Iterate through the repository and find components that can be included */
|
||||||
|
OPAL_LIST_FOREACH(ri, dy_components, mca_base_component_repository_item_t) {
|
||||||
char *err_msg;
|
if (use_component(include_mode, names, ri->ri_name)) {
|
||||||
if (OPAL_SUCCESS !=
|
mca_base_component_repository_open (framework, ri);
|
||||||
opal_dl_open(target_file->filename, true, false, &component_handle,
|
|
||||||
&err_msg)) {
|
|
||||||
if (NULL != err_msg) {
|
|
||||||
err_msg = strdup(err_msg);
|
|
||||||
} else {
|
|
||||||
err_msg = strdup("opal_dl_open() error message was NULL!");
|
|
||||||
}
|
|
||||||
/* Because libltdl erroneously says "file not found" for any
|
|
||||||
type of error -- which is especially misleading when the file
|
|
||||||
is actually there but cannot be opened for some other reason
|
|
||||||
(e.g., missing symbol) -- do some simple huersitics and if
|
|
||||||
the file [probably] does exist, print a slightly better error
|
|
||||||
message. */
|
|
||||||
if (0 == strcmp("file not found", err_msg) &&
|
|
||||||
(file_exists(target_file->filename, "lo") ||
|
|
||||||
file_exists(target_file->filename, "so") ||
|
|
||||||
file_exists(target_file->filename, "dylib") ||
|
|
||||||
file_exists(target_file->filename, "dll"))) {
|
|
||||||
free(err_msg);
|
|
||||||
err_msg = strdup("perhaps a missing symbol, or compiled for a different version of Open MPI?");
|
|
||||||
}
|
|
||||||
opal_output_verbose(vl, 0, "mca: base: component_find: unable to open %s: %s (ignored)",
|
|
||||||
target_file->filename, err_msg);
|
|
||||||
free(err_msg);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Successfully opened the component; now find the public struct.
|
|
||||||
Malloc out enough space for it. */
|
|
||||||
|
|
||||||
len = strlen(target_file->type) + strlen(target_file->name) + 32;
|
|
||||||
struct_name = (char*)malloc(len);
|
|
||||||
if (NULL == struct_name) {
|
|
||||||
opal_dl_close(component_handle);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
snprintf(struct_name, len, "mca_%s_%s_component", target_file->type,
|
|
||||||
target_file->name);
|
|
||||||
|
|
||||||
mitem = OBJ_NEW(mca_base_component_list_item_t);
|
|
||||||
if (NULL == mitem) {
|
|
||||||
free(struct_name);
|
|
||||||
opal_dl_close(component_handle);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OPAL_SUCCESS != opal_dl_lookup(component_handle, struct_name,
|
|
||||||
(void**) &component_struct, &err_msg) ||
|
|
||||||
NULL == component_struct) {
|
|
||||||
if (NULL == err_msg) {
|
|
||||||
err_msg = "opal_dl_loookup() error message was NULL!";
|
|
||||||
}
|
|
||||||
opal_output_verbose(vl, 0, "mca: base: component_find: \"%s\" does not appear to be a valid "
|
|
||||||
"%s MCA dynamic component (ignored): %s",
|
|
||||||
target_file->basename, target_file->type, err_msg);
|
|
||||||
free(mitem);
|
|
||||||
free(struct_name);
|
|
||||||
opal_dl_close(component_handle);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We found the public struct. Make sure its MCA major.minor
|
|
||||||
version is the same as ours. */
|
|
||||||
if (!(MCA_BASE_VERSION_MAJOR == component_struct->mca_major_version &&
|
|
||||||
MCA_BASE_VERSION_MINOR == component_struct->mca_minor_version)) {
|
|
||||||
opal_output_verbose(vl, 0, "mca: base: component_find: %s \"%s\" uses an MCA interface that is not recognized (component MCA v%d.%d.%d != supported MCA v%d.%d.%d) -- ignored",
|
|
||||||
target_file->type, target_file->basename,
|
|
||||||
component_struct->mca_major_version,
|
|
||||||
component_struct->mca_minor_version,
|
|
||||||
component_struct->mca_release_version,
|
|
||||||
MCA_BASE_VERSION_MAJOR,
|
|
||||||
MCA_BASE_VERSION_MINOR,
|
|
||||||
MCA_BASE_VERSION_RELEASE);
|
|
||||||
free(mitem);
|
|
||||||
free(struct_name);
|
|
||||||
opal_dl_close(component_handle);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Also check that the component struct framework and component
|
|
||||||
names match the expected names from the filename */
|
|
||||||
if (0 != strcmp(component_struct->mca_type_name, target_file->type) ||
|
|
||||||
0 != strcmp(component_struct->mca_component_name, target_file->name)) {
|
|
||||||
opal_output_verbose(vl, 0, "Component file data does not match filename: %s (%s / %s) != %s %s -- ignored",
|
|
||||||
target_file->filename, target_file->type, target_file->name,
|
|
||||||
component_struct->mca_type_name,
|
|
||||||
component_struct->mca_component_name);
|
|
||||||
free(mitem);
|
|
||||||
free(struct_name);
|
|
||||||
opal_dl_close(component_handle);
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
free_dependency_list(&dependencies);
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alles gut. Save the component struct, and register this
|
|
||||||
component to be closed later. */
|
|
||||||
|
|
||||||
mitem->cli_component = component_struct;
|
|
||||||
opal_list_append(found_components, (opal_list_item_t *) mitem);
|
|
||||||
mca_base_component_repository_retain(target_file->type, component_handle,
|
|
||||||
component_struct);
|
|
||||||
|
|
||||||
/* Now that that's all done, link all the dependencies in to this
|
|
||||||
component's repository entry */
|
|
||||||
|
|
||||||
for (cur = opal_list_remove_first(&dependencies);
|
|
||||||
NULL != cur;
|
|
||||||
cur = opal_list_remove_first(&dependencies)) {
|
|
||||||
ditem = (dependency_item_t *) cur;
|
|
||||||
mca_base_component_repository_link(target_file->type,
|
|
||||||
target_file->name,
|
|
||||||
ditem->di_component_file_item->type,
|
|
||||||
ditem->di_component_file_item->name);
|
|
||||||
OBJ_RELEASE(ditem);
|
|
||||||
}
|
|
||||||
OBJ_DESTRUCT(&dependencies);
|
|
||||||
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: opened dynamic %s MCA component \"%s\"",
|
|
||||||
target_file->type, target_file->name);
|
|
||||||
target_file->status = LOADED;
|
|
||||||
|
|
||||||
/* All done */
|
|
||||||
|
|
||||||
free(struct_name);
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For a given filename, see if there exists a filename.ompi_info, which
|
|
||||||
* lists dependencies that must be loaded before this component is
|
|
||||||
* loaded. If we find this file, try to load those components first.
|
|
||||||
*
|
|
||||||
* Detect dependency cycles and error out.
|
|
||||||
*/
|
|
||||||
static int check_opal_info(component_file_item_t *target_file,
|
|
||||||
opal_list_t *dependencies,
|
|
||||||
opal_list_t *found_components)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
FILE *fp;
|
|
||||||
char *depname;
|
|
||||||
char buffer[BUFSIZ], *p;
|
|
||||||
|
|
||||||
/* Form the filename */
|
|
||||||
|
|
||||||
len = strlen(target_file->filename) + strlen(opal_info_suffix) + 16;
|
|
||||||
depname = (char*)malloc(len);
|
|
||||||
if (NULL == depname)
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
snprintf(depname, len, "%s%s", target_file->filename, opal_info_suffix);
|
|
||||||
|
|
||||||
/* Try to open the file. If there's no file, return success (i.e.,
|
|
||||||
there are no dependencies). */
|
|
||||||
|
|
||||||
if (NULL == (fp = fopen(depname, "r"))) {
|
|
||||||
free(depname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, loop reading the lines in the file and trying to load
|
|
||||||
them. Return failure upon the first component that fails to
|
|
||||||
load. */
|
|
||||||
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: opening .ompi_info file: %s", depname);
|
|
||||||
while (NULL != fgets(buffer, BUFSIZ, fp)) {
|
|
||||||
|
|
||||||
/* Perl chomp */
|
|
||||||
|
|
||||||
buffer[BUFSIZ - 1] = '\0';
|
|
||||||
len = strlen(buffer);
|
|
||||||
if ('\n' == buffer[len - 1])
|
|
||||||
buffer[len - 1] = '\0';
|
|
||||||
|
|
||||||
/* Ignore emtpy lines and lines beginning with "#" or "//" */
|
|
||||||
|
|
||||||
for (p = buffer; '\0' != p; ++p)
|
|
||||||
if (!isspace(*p))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ('\0' == *p)
|
|
||||||
continue;
|
|
||||||
else if (*p == '#' || ('/' == *p && '/' == *(p + 1)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Is it a dependency? */
|
|
||||||
|
|
||||||
else if (0 == strncasecmp(p, key_dependency, strlen(key_dependency))) {
|
|
||||||
if (OPAL_SUCCESS != check_dependency(p + strlen(key_dependency),
|
|
||||||
target_file, dependencies,
|
|
||||||
found_components)) {
|
|
||||||
fclose(fp);
|
|
||||||
free(depname);
|
|
||||||
|
|
||||||
/* We can leave any successfully loaded dependencies; we might
|
|
||||||
need them again later. But free the dependency list for
|
|
||||||
this component, because since [at least] one of them didn't
|
|
||||||
load, we have to pretend like all of them didn't load and
|
|
||||||
disallow loading this component. So free the dependency
|
|
||||||
list. */
|
|
||||||
|
|
||||||
free_dependency_list(dependencies);
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: ompi_info file closed (%s)",
|
|
||||||
target_file->basename);
|
|
||||||
|
|
||||||
/* All done -- all depenencies satisfied */
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
free(depname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A DEPENDENCY key was found in the ompi_info file. Chase it down: see
|
|
||||||
* if we've already got such a component loaded, or go try to load it if
|
|
||||||
* it's not already loaded.
|
|
||||||
*/
|
|
||||||
static int check_dependency(char *line, component_file_item_t *target_file,
|
|
||||||
opal_list_t *dependencies,
|
|
||||||
opal_list_t *found_components)
|
|
||||||
{
|
|
||||||
bool happiness;
|
|
||||||
char buffer[BUFSIZ];
|
|
||||||
char *type, *name;
|
|
||||||
int len;
|
|
||||||
component_file_item_t *mitem;
|
|
||||||
dependency_item_t *ditem;
|
|
||||||
opal_list_item_t *cur;
|
|
||||||
|
|
||||||
/* Ensure that this was a valid dependency statement */
|
|
||||||
|
|
||||||
type = line;
|
|
||||||
name = strchr(line, OPAL_ENV_SEP);
|
|
||||||
if (NULL == name) {
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
*name = '\0';
|
|
||||||
++name;
|
|
||||||
|
|
||||||
/* Form the name of the component to compare to */
|
|
||||||
|
|
||||||
if (strlen(type) + strlen(name) + 32 >= BUFSIZ) {
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
snprintf(buffer, BUFSIZ, component_template, type);
|
|
||||||
len = strlen(buffer);
|
|
||||||
strncat(buffer, name, BUFSIZ - len);
|
|
||||||
|
|
||||||
/* Traverse down the list of files that we have, and see if we can
|
|
||||||
find it */
|
|
||||||
|
|
||||||
mitem = NULL;
|
|
||||||
target_file->status = CHECKING_CYCLE;
|
|
||||||
for (happiness = false, cur = opal_list_get_first(&found_files);
|
|
||||||
opal_list_get_end(&found_files) != cur;
|
|
||||||
cur = opal_list_get_next(cur)) {
|
|
||||||
mitem = (component_file_item_t *) cur;
|
|
||||||
|
|
||||||
/* Compare the name to the basename */
|
|
||||||
|
|
||||||
if (0 != strcmp(mitem->basename, buffer))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Catch the bozo dependency on itself */
|
|
||||||
|
|
||||||
else if (mitem == target_file) {
|
|
||||||
opal_output_verbose(40, 0,
|
|
||||||
"mca: base: component_find: component depends on itself (ignored dependency)");
|
|
||||||
happiness = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it's loaded, great -- we're done (no need to check that
|
|
||||||
dependency sub-tree) */
|
|
||||||
|
|
||||||
else if (LOADED == mitem->status) {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: dependency has already been loaded (%s)",
|
|
||||||
mitem->basename);
|
|
||||||
happiness = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it's specifically not loaded (i.e., there was some kind of
|
|
||||||
error when we tried to load it), then we cannot meet the
|
|
||||||
dependencies. */
|
|
||||||
|
|
||||||
else if (FAILED_TO_LOAD == mitem->status) {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: dependency previously failed to load (%s)",
|
|
||||||
mitem->basename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we hit a cycle, return badness */
|
|
||||||
|
|
||||||
else if (CHECKING_CYCLE == mitem->status) {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: found cycle! (%s)",
|
|
||||||
mitem->basename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, this dependency has not been looked at yet. Go try
|
|
||||||
to load it. */
|
|
||||||
|
|
||||||
else if (UNVISITED == mitem->status) {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: loading dependency (%s)",
|
|
||||||
mitem->basename);
|
|
||||||
if (OPAL_SUCCESS == open_component(target_file, found_components)) {
|
|
||||||
happiness = true;
|
|
||||||
} else {
|
|
||||||
opal_output_verbose(40, 0, "mca: base: component_find: dependency failed to load (%s)",
|
|
||||||
mitem->basename);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Did we find the dependency? */
|
|
||||||
|
|
||||||
if (!happiness) {
|
|
||||||
target_file->status = FAILED_TO_LOAD;
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The dependency loaded properly. Increment its refcount so that
|
|
||||||
it doesn't get unloaded before we get unloaded. The (NULL !=
|
|
||||||
mitem) check is somewhat redundant -- we won't be here in this
|
|
||||||
function unless there's dependencies to check, but a) it's safer
|
|
||||||
to double check, and b) it fixes a compiler warning. :-) */
|
|
||||||
|
|
||||||
if (NULL != mitem) {
|
|
||||||
ditem = OBJ_NEW(dependency_item_t);
|
|
||||||
if (NULL == ditem) {
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
ditem->di_component_file_item = mitem;
|
|
||||||
opal_list_append(dependencies, (opal_list_item_t*) ditem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All done -- all depenencies satisfied */
|
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free a dependency list
|
|
||||||
*/
|
|
||||||
static void free_dependency_list(opal_list_t *dependencies)
|
|
||||||
{
|
|
||||||
opal_list_item_t *item;
|
|
||||||
|
|
||||||
for (item = opal_list_remove_first(dependencies);
|
|
||||||
NULL != item;
|
|
||||||
item = opal_list_remove_first(dependencies)) {
|
|
||||||
OBJ_RELEASE(item);
|
|
||||||
}
|
|
||||||
OBJ_DESTRUCT(dependencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
|
||||||
@ -970,13 +307,16 @@ static bool use_component(const bool include_mode,
|
|||||||
|
|
||||||
/* Ensure that *all* requested components exist. Print a warning
|
/* Ensure that *all* requested components exist. Print a warning
|
||||||
and abort if they do not. */
|
and abort if they do not. */
|
||||||
static int component_find_check (const char *framework_name, char **requested_component_names, opal_list_t *components)
|
static int component_find_check (mca_base_framework_t *framework, char **requested_component_names)
|
||||||
{
|
{
|
||||||
|
opal_list_t *components = &framework->framework_components;
|
||||||
mca_base_component_list_item_t *cli;
|
mca_base_component_list_item_t *cli;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; NULL != requested_component_names &&
|
if (NULL == requested_component_names) {
|
||||||
NULL != requested_component_names[i]; ++i) {
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; NULL != requested_component_names[i]; ++i) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
OPAL_LIST_FOREACH(cli, components, mca_base_component_list_item_t) {
|
OPAL_LIST_FOREACH(cli, components, mca_base_component_list_item_t) {
|
||||||
@ -992,7 +332,7 @@ static int component_find_check (const char *framework_name, char **requested_co
|
|||||||
gethostname(h, sizeof(h));
|
gethostname(h, sizeof(h));
|
||||||
opal_show_help("help-mca-base.txt",
|
opal_show_help("help-mca-base.txt",
|
||||||
"find-available:not-valid", true,
|
"find-available:not-valid", true,
|
||||||
h, framework_name, requested_component_names[i]);
|
h, framework->framework_name, requested_component_names[i]);
|
||||||
return OPAL_ERR_NOT_FOUND;
|
return OPAL_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
* University Research and Technology
|
* University Research and Technology
|
||||||
@ -10,6 +11,8 @@
|
|||||||
* 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) 2008-2015 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
|
||||||
|
* reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -32,37 +35,19 @@
|
|||||||
#include "opal/mca/base/mca_base_component_repository.h"
|
#include "opal/mca/base/mca_base_component_repository.h"
|
||||||
#include "opal/mca/dl/base/base.h"
|
#include "opal/mca/dl/base/base.h"
|
||||||
#include "opal/constants.h"
|
#include "opal/constants.h"
|
||||||
|
#include "opal/class/opal_hash_table.h"
|
||||||
|
#include "opal/util/basename.h"
|
||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private types
|
* Private types
|
||||||
*/
|
*/
|
||||||
struct repository_item_t {
|
static void ri_constructor(mca_base_component_repository_item_t *ri);
|
||||||
opal_list_item_t super;
|
static void ri_destructor(mca_base_component_repository_item_t *ri);
|
||||||
|
OBJ_CLASS_INSTANCE(mca_base_component_repository_item_t, opal_list_item_t,
|
||||||
char ri_type[MCA_BASE_MAX_TYPE_NAME_LEN + 1];
|
|
||||||
opal_dl_handle_t *ri_dlhandle;
|
|
||||||
const mca_base_component_t *ri_component_struct;
|
|
||||||
opal_list_t ri_dependencies;
|
|
||||||
};
|
|
||||||
typedef struct repository_item_t repository_item_t;
|
|
||||||
static void ri_constructor(opal_object_t *obj);
|
|
||||||
static void ri_destructor(opal_object_t *obj);
|
|
||||||
static OBJ_CLASS_INSTANCE(repository_item_t, opal_list_item_t,
|
|
||||||
ri_constructor, ri_destructor);
|
ri_constructor, ri_destructor);
|
||||||
|
|
||||||
struct dependency_item_t {
|
|
||||||
opal_list_item_t super;
|
|
||||||
|
|
||||||
repository_item_t *di_repository_entry;
|
|
||||||
};
|
|
||||||
typedef struct dependency_item_t dependency_item_t;
|
|
||||||
static void di_constructor(opal_object_t *obj);
|
|
||||||
static void di_destructor(opal_object_t *obj);
|
|
||||||
static OBJ_CLASS_INSTANCE(dependency_item_t, opal_list_item_t,
|
|
||||||
di_constructor, di_destructor);
|
|
||||||
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
|
||||||
|
|
||||||
@ -74,17 +59,149 @@ static bool initialized = false;
|
|||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
|
||||||
static opal_list_t repository;
|
static opal_hash_table_t mca_base_component_repository;
|
||||||
|
|
||||||
|
/* two-level macro for stringifying a number */
|
||||||
|
#define STRINGIFYX(x) #x
|
||||||
|
#define STRINGIFY(x) STRINGIFYX(x)
|
||||||
|
|
||||||
/*
|
static int process_repository_item (const char *filename, void *data)
|
||||||
* Private functions
|
{
|
||||||
*/
|
char name[MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
|
||||||
static repository_item_t *find_component(const char *type, const char *name);
|
char type[MCA_BASE_MAX_TYPE_NAME_LEN + 1];
|
||||||
static int link_items(repository_item_t *src, repository_item_t *depend);
|
mca_base_component_repository_item_t *ri;
|
||||||
|
opal_list_t *component_list;
|
||||||
|
char *base;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
base = opal_basename (filename);
|
||||||
|
if (NULL == base) {
|
||||||
|
return OPAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the plugin has the appropriate prefix */
|
||||||
|
if (0 != strncmp (base, "mca_", 4)) {
|
||||||
|
free (base);
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read framework and component names. framework names may not include an _
|
||||||
|
* but component names may */
|
||||||
|
ret = sscanf (base, "mca_%" STRINGIFY(MCA_BASE_MAX_TYPE_NAME_LEN) "[^_]_%"
|
||||||
|
STRINGIFY(MCA_BASE_MAX_COMPONENT_NAME_LEN) "s", type, name);
|
||||||
|
if (0 > ret) {
|
||||||
|
/* does not patch the expected template. skip */
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lookup the associated framework list and create if it doesn't already exist */
|
||||||
|
ret = opal_hash_table_get_value_ptr (&mca_base_component_repository, type,
|
||||||
|
strlen (type), (void **) &component_list);
|
||||||
|
if (OPAL_SUCCESS != ret) {
|
||||||
|
component_list = OBJ_NEW(opal_list_t);
|
||||||
|
if (NULL == component_list) {
|
||||||
|
free (base);
|
||||||
|
/* OOM. nothing to do but fail */
|
||||||
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = opal_hash_table_set_value_ptr (&mca_base_component_repository, type,
|
||||||
|
strlen (type), (void *) component_list);
|
||||||
|
if (OPAL_SUCCESS != ret) {
|
||||||
|
free (base);
|
||||||
|
OBJ_RELEASE(component_list);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for duplicate components */
|
||||||
|
OPAL_LIST_FOREACH(ri, component_list, mca_base_component_repository_item_t) {
|
||||||
|
if (0 == strcmp (ri->ri_name, name)) {
|
||||||
|
/* already scanned this component */
|
||||||
|
free (base);
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ri = OBJ_NEW(mca_base_component_repository_item_t);
|
||||||
|
if (NULL == ri) {
|
||||||
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ri->ri_base = base;
|
||||||
|
|
||||||
|
ri->ri_path = strdup (filename);
|
||||||
|
if (NULL == ri->ri_path) {
|
||||||
|
OBJ_RELEASE(ri);
|
||||||
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strncpy does not guarantee a \0 */
|
||||||
|
ri->ri_type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
|
||||||
|
strncpy (ri->ri_type, type, MCA_BASE_MAX_TYPE_NAME_LEN);
|
||||||
|
|
||||||
|
ri->ri_name[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
|
||||||
|
strncpy (ri->ri_name, name, MCA_BASE_MAX_COMPONENT_NAME_LEN);
|
||||||
|
|
||||||
|
opal_list_append (component_list, &ri->super);
|
||||||
|
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_exists(const char *filename, const char *ext)
|
||||||
|
{
|
||||||
|
char *final;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (NULL == ext) {
|
||||||
|
return access (filename, F_OK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = asprintf(&final, "%s.%s", filename, ext);
|
||||||
|
if (0 > ret || NULL == final) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = access (final, F_OK);
|
||||||
|
free(final);
|
||||||
|
return (0 == ret);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
|
||||||
|
int mca_base_component_repository_add (const char *path)
|
||||||
|
{
|
||||||
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
char *path_to_use = NULL, *dir, *ctx;
|
||||||
|
const char sep[] = {OPAL_ENV_SEP, '\0'};
|
||||||
|
|
||||||
|
if (NULL == path) {
|
||||||
|
/* nothing to do */
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_to_use = strdup (path);
|
||||||
|
|
||||||
|
dir = strtok_r (path_to_use, sep, &ctx);
|
||||||
|
do {
|
||||||
|
if ((0 == strcmp(dir, "USER_DEFAULT") || 0 == strcmp(dir, "USR_DEFAULT"))
|
||||||
|
&& NULL != mca_base_user_default_path) {
|
||||||
|
dir = mca_base_user_default_path;
|
||||||
|
} else if (0 == strcmp(dir, "SYS_DEFAULT") ||
|
||||||
|
0 == strcmp(dir, "SYSTEM_DEFAULT")) {
|
||||||
|
dir = mca_base_system_default_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != opal_dl_foreachfile(dir, process_repository_item, NULL)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (NULL != (dir = strtok_r (NULL, sep, &ctx)));
|
||||||
|
|
||||||
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the repository
|
* Initialize the repository
|
||||||
@ -105,7 +222,19 @@ int mca_base_component_repository_init(void)
|
|||||||
}
|
}
|
||||||
opal_dl_base_select();
|
opal_dl_base_select();
|
||||||
|
|
||||||
OBJ_CONSTRUCT(&repository, opal_list_t);
|
OBJ_CONSTRUCT(&mca_base_component_repository, opal_hash_table_t);
|
||||||
|
ret = opal_hash_table_init (&mca_base_component_repository, 128);
|
||||||
|
if (OPAL_SUCCESS != ret) {
|
||||||
|
mca_base_framework_close (&opal_dl_base_framework);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mca_base_component_repository_add (mca_base_component_path);
|
||||||
|
if (OPAL_SUCCESS != ret) {
|
||||||
|
OBJ_DESTRUCT(&mca_base_component_repository);
|
||||||
|
mca_base_framework_close (&opal_dl_base_framework);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
@ -116,279 +245,282 @@ int mca_base_component_repository_init(void)
|
|||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mca_base_component_repository_get_components (mca_base_framework_t *framework,
|
||||||
|
opal_list_t **framework_components)
|
||||||
|
{
|
||||||
|
*framework_components = NULL;
|
||||||
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
return opal_hash_table_get_value_ptr (&mca_base_component_repository, framework->framework_name,
|
||||||
|
strlen (framework->framework_name), (void **) framework_components);
|
||||||
|
#endif
|
||||||
|
return OPAL_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
static void mca_base_component_repository_release_internal (mca_base_component_repository_item_t *ri) {
|
||||||
* Add a newly-opened dyanmic component to the repository of open
|
int group_id;
|
||||||
* components. The component's type, handle, and public struct are
|
|
||||||
* saved.
|
group_id = mca_base_var_group_find (NULL, ri->ri_type, ri->ri_name);
|
||||||
*/
|
if (0 <= group_id) {
|
||||||
int mca_base_component_repository_retain(char *type,
|
/* ensure all variables are deregistered before we dlclose the component */
|
||||||
opal_dl_handle_t *component_handle,
|
mca_base_var_group_deregister (group_id);
|
||||||
const mca_base_component_t *component_struct)
|
}
|
||||||
|
|
||||||
|
/* Close the component (and potentially unload it from memory */
|
||||||
|
if (ri->ri_dlhandle) {
|
||||||
|
opal_dl_close(ri->ri_dlhandle);
|
||||||
|
ri->ri_dlhandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mca_base_component_repository_release(const mca_base_component_t *component)
|
||||||
|
{
|
||||||
|
mca_base_component_repository_item_t *ri;
|
||||||
|
opal_list_t *component_list;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = opal_hash_table_get_value_ptr (&mca_base_component_repository, component->mca_type_name,
|
||||||
|
strlen (component->mca_type_name), (void **) &component_list);
|
||||||
|
if (OPAL_SUCCESS != ret) {
|
||||||
|
/* component does not exist in the repository */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OPAL_LIST_FOREACH(ri, component_list, mca_base_component_repository_item_t) {
|
||||||
|
if (0 == strcmp (ri->ri_name, component->mca_component_name)) {
|
||||||
|
/* go ahead and dlclose the component if it is open */
|
||||||
|
mca_base_component_repository_release_internal (ri);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mca_base_component_repository_open (mca_base_framework_t *framework,
|
||||||
|
mca_base_component_repository_item_t *ri)
|
||||||
{
|
{
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
repository_item_t *ri;
|
mca_base_component_t *component_struct;
|
||||||
|
mca_base_component_list_item_t *mitem = NULL;
|
||||||
|
char *struct_name = NULL;
|
||||||
|
int vl, ret;
|
||||||
|
|
||||||
/* Allocate a new repository item */
|
opal_output_verbose(40, 0, "mca_base_component_repository_open: examining dynamic %s MCA component \"%s\" at path %s",
|
||||||
|
ri->ri_type, ri->ri_name, ri->ri_path);
|
||||||
|
|
||||||
ri = OBJ_NEW(repository_item_t);
|
vl = mca_base_component_show_load_errors ? 0 : 40;
|
||||||
if (NULL == ri) {
|
|
||||||
|
/* 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.
|
||||||
|
Hence, returning OPAL_ERR_PARAM indicates that the *file* failed
|
||||||
|
to load, not the component. */
|
||||||
|
|
||||||
|
OPAL_LIST_FOREACH(mitem, &framework->framework_components, mca_base_component_list_item_t) {
|
||||||
|
if (0 == strcmp(mitem->cli_component->mca_component_name, ri->ri_name)) {
|
||||||
|
opal_output_verbose(40, 0, "mca_base_component_repository_open: already loaded (ignored)");
|
||||||
|
return OPAL_ERR_BAD_PARAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != ri->ri_dlhandle) {
|
||||||
|
opal_output_verbose(40, 0, "mca_base_component_repository_open: already loaded. returning cached component");
|
||||||
|
mitem = OBJ_NEW(mca_base_component_list_item_t);
|
||||||
|
if (NULL == mitem) {
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the repository item */
|
mitem->cli_component = ri->ri_component_struct;
|
||||||
|
opal_list_append (&framework->framework_components, &mitem->super);
|
||||||
strncpy(ri->ri_type, type, MCA_BASE_MAX_TYPE_NAME_LEN);
|
|
||||||
ri->ri_type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0';
|
|
||||||
ri->ri_dlhandle = component_handle;
|
|
||||||
ri->ri_component_struct = component_struct;
|
|
||||||
|
|
||||||
/* Append the new item to the repository */
|
|
||||||
|
|
||||||
opal_list_append(&repository, (opal_list_item_t *) ri);
|
|
||||||
|
|
||||||
/* All done */
|
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
#else
|
}
|
||||||
|
|
||||||
|
if (0 != strcmp (ri->ri_type, framework->framework_name)) {
|
||||||
|
/* shouldn't happen. attempting to open a component belonging to
|
||||||
|
* another framework. if this happens it is likely a MCA base
|
||||||
|
* bug so assert */
|
||||||
|
assert (0);
|
||||||
return OPAL_ERR_NOT_SUPPORTED;
|
return OPAL_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now try to load the component */
|
||||||
|
|
||||||
/*
|
char *err_msg = NULL;
|
||||||
* Bump up the refcount on a component
|
if (OPAL_SUCCESS != opal_dl_open(ri->ri_path, true, false, &ri->ri_dlhandle, &err_msg)) {
|
||||||
*/
|
if (NULL == err_msg) {
|
||||||
int mca_base_component_repository_retain_component(const char *type,
|
err_msg = "opal_dl_open() error message was NULL!";
|
||||||
const char *name)
|
|
||||||
{
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
repository_item_t *ri = find_component(type, name);
|
|
||||||
if (NULL != ri) {
|
|
||||||
OBJ_RETAIN(ri);
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
}
|
||||||
return OPAL_ERR_NOT_FOUND;
|
/* Because libltdl erroneously says "file not found" for any
|
||||||
#else
|
type of error -- which is especially misleading when the file
|
||||||
return OPAL_ERR_NOT_SUPPORTED;
|
is actually there but cannot be opened for some other reason
|
||||||
#endif
|
(e.g., missing symbol) -- do some simple huersitics and if
|
||||||
|
the file [probably] does exist, print a slightly better error
|
||||||
|
message. */
|
||||||
|
if (0 == strcasecmp("file not found", err_msg) &&
|
||||||
|
(file_exists(ri->ri_path, "lo") ||
|
||||||
|
file_exists(ri->ri_path, "so") ||
|
||||||
|
file_exists(ri->ri_path, "dylib") ||
|
||||||
|
file_exists(ri->ri_path, "dll"))) {
|
||||||
|
err_msg = "perhaps a missing symbol, or compiled for a different version of Open MPI?";
|
||||||
}
|
}
|
||||||
|
opal_output_verbose(vl, 0, "mca_base_component_repository_open: unable to open %s: %s (ignored)",
|
||||||
|
ri->ri_base, err_msg);
|
||||||
/*
|
|
||||||
* Create a dependency from one component entry to another
|
|
||||||
*/
|
|
||||||
int mca_base_component_repository_link(const char *src_type,
|
|
||||||
const char *src_name,
|
|
||||||
const char *depend_type,
|
|
||||||
const char *depend_name)
|
|
||||||
{
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
repository_item_t *src, *depend;
|
|
||||||
|
|
||||||
/* Look up the two components */
|
|
||||||
|
|
||||||
src = find_component(src_type, src_name);
|
|
||||||
if (NULL == src) {
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
depend = find_component(depend_type, depend_name);
|
|
||||||
if (NULL == depend) {
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
return OPAL_ERR_BAD_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link them */
|
/* Successfully opened the component; now find the public struct.
|
||||||
|
Malloc out enough space for it. */
|
||||||
|
|
||||||
return link_items(src, depend);
|
do {
|
||||||
|
ret = asprintf (&struct_name, "mca_%s_%s_component", ri->ri_type, ri->ri_name);
|
||||||
|
if (0 > ret) {
|
||||||
|
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mitem = OBJ_NEW(mca_base_component_list_item_t);
|
||||||
|
if (NULL == mitem) {
|
||||||
|
ret = OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_msg = NULL;
|
||||||
|
ret = opal_dl_lookup(ri->ri_dlhandle, struct_name, (void**) &component_struct, &err_msg);
|
||||||
|
if (OPAL_SUCCESS != ret || NULL == component_struct) {
|
||||||
|
if (NULL == err_msg) {
|
||||||
|
err_msg = "opal_dl_loookup() error message was NULL!";
|
||||||
|
}
|
||||||
|
opal_output_verbose(vl, 0, "mca_base_component_repository_open: \"%s\" does not appear to be a valid "
|
||||||
|
"%s MCA dynamic component (ignored): %s. ret %d", ri->ri_base, ri->ri_type, err_msg, ret);
|
||||||
|
|
||||||
|
ret = OPAL_ERR_BAD_PARAM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done with the structure name */
|
||||||
|
free (struct_name);
|
||||||
|
|
||||||
|
/* We found the public struct. Make sure its MCA major.minor
|
||||||
|
version is the same as ours. TODO -- add checks for project version (from framework) */
|
||||||
|
if (!(MCA_BASE_VERSION_MAJOR == component_struct->mca_major_version &&
|
||||||
|
MCA_BASE_VERSION_MINOR == component_struct->mca_minor_version)) {
|
||||||
|
opal_output_verbose(vl, 0, "mca_base_component_repository_open: %s \"%s\" uses an MCA interface that is "
|
||||||
|
"not recognized (component MCA v%d.%d.%d != supported MCA v%d.%d.%d) -- ignored",
|
||||||
|
ri->ri_type, ri->ri_path, component_struct->mca_major_version,
|
||||||
|
component_struct->mca_minor_version, component_struct->mca_release_version,
|
||||||
|
MCA_BASE_VERSION_MAJOR, MCA_BASE_VERSION_MINOR, MCA_BASE_VERSION_RELEASE);
|
||||||
|
ret = OPAL_ERR_BAD_PARAM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Also check that the component struct framework and component
|
||||||
|
names match the expected names from the filename */
|
||||||
|
if (0 != strcmp(component_struct->mca_type_name, ri->ri_type) ||
|
||||||
|
0 != strcmp(component_struct->mca_component_name, ri->ri_name)) {
|
||||||
|
opal_output_verbose(vl, 0, "Component file data does not match filename: %s (%s / %s) != %s %s -- ignored",
|
||||||
|
ri->ri_path, ri->ri_type, ri->ri_name,
|
||||||
|
component_struct->mca_type_name,
|
||||||
|
component_struct->mca_component_name);
|
||||||
|
ret = OPAL_ERR_BAD_PARAM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alles gut. Save the component struct, and register this
|
||||||
|
component to be closed later. */
|
||||||
|
|
||||||
|
ri->ri_component_struct = mitem->cli_component = component_struct;
|
||||||
|
opal_list_append(&framework->framework_components, &mitem->super);
|
||||||
|
|
||||||
|
opal_output_verbose(40, 0, "mca_base_component_repository_open: opened dynamic %s MCA component \"%s\"",
|
||||||
|
ri->ri_type, ri->ri_name);
|
||||||
|
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
if (mitem) {
|
||||||
|
OBJ_RELEASE(mitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (struct_name) {
|
||||||
|
free (struct_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
opal_dl_close (ri->ri_dlhandle);
|
||||||
|
ri->ri_dlhandle = NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* no dlopen support */
|
||||||
return OPAL_ERR_NOT_SUPPORTED;
|
return OPAL_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If it's in the repository, close a specified component and remove
|
|
||||||
* it from the repository.
|
|
||||||
*/
|
|
||||||
void mca_base_component_repository_release(const mca_base_component_t *component)
|
|
||||||
{
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
if (initialized) {
|
|
||||||
repository_item_t *ri = find_component(component->mca_type_name,
|
|
||||||
component->mca_component_name);
|
|
||||||
if (NULL != ri) {
|
|
||||||
OBJ_RELEASE(ri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finalize the repository -- close everything that's still open.
|
* Finalize the repository -- close everything that's still open.
|
||||||
*/
|
*/
|
||||||
void mca_base_component_repository_finalize(void)
|
void mca_base_component_repository_finalize(void)
|
||||||
{
|
{
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
if (!initialized) {
|
||||||
repository_item_t *ri, *next;
|
return;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (initialized) {
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
|
||||||
|
|
||||||
/* Have to be slightly careful about this because of dependencies,
|
|
||||||
particularly on OS's where it matters (i.e., closing a
|
|
||||||
component that is depended on by other components actually
|
|
||||||
causes missing symbols because the OS actually does unload it
|
|
||||||
from memory!), such as OS X.
|
|
||||||
|
|
||||||
So instead of just blindly closing everything, we have iterate
|
|
||||||
over the array of open components releasing everything with a
|
|
||||||
refcount of 1 -- skip anything with a refcount of more than 1.
|
|
||||||
Repeat this procedure until either we have nothing open or we
|
|
||||||
made one full pass and no refcounts went to 1 (which is
|
|
||||||
technically an error). */
|
|
||||||
|
|
||||||
do {
|
|
||||||
OPAL_LIST_FOREACH_SAFE(ri, next, &repository, repository_item_t) {
|
|
||||||
OBJ_RELEASE(ri);
|
|
||||||
}
|
}
|
||||||
} while (opal_list_get_size(&repository) > 0);
|
|
||||||
|
|
||||||
(void) mca_base_framework_close(&opal_dl_base_framework);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
|
||||||
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
opal_list_t *component_list;
|
||||||
|
void *node, *key;
|
||||||
|
size_t key_size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = opal_hash_table_get_first_key_ptr (&mca_base_component_repository, &key, &key_size,
|
||||||
|
(void **) &component_list, &node);
|
||||||
|
while (OPAL_SUCCESS == ret) {
|
||||||
|
OPAL_LIST_RELEASE(component_list);
|
||||||
|
ret = opal_hash_table_get_next_key_ptr (&mca_base_component_repository, &key,
|
||||||
|
&key_size, (void **) &component_list,
|
||||||
|
node, &node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(void) mca_base_framework_close(&opal_dl_base_framework);
|
||||||
|
OBJ_DESTRUCT(&mca_base_component_repository);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPAL_HAVE_DL_SUPPORT
|
#if OPAL_HAVE_DL_SUPPORT
|
||||||
|
|
||||||
static repository_item_t *find_component(const char *type, const char *name)
|
|
||||||
{
|
|
||||||
opal_list_item_t *item;
|
|
||||||
repository_item_t *ri;
|
|
||||||
|
|
||||||
for (item = opal_list_get_first(&repository);
|
|
||||||
opal_list_get_end(&repository) != item;
|
|
||||||
item = opal_list_get_next(item)) {
|
|
||||||
ri = (repository_item_t *) item;
|
|
||||||
if (0 == strcmp(ri->ri_type, type) &&
|
|
||||||
0 == strcmp(ri->ri_component_struct->mca_component_name, name)) {
|
|
||||||
return ri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not found */
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int link_items(repository_item_t *src, repository_item_t *depend)
|
|
||||||
{
|
|
||||||
dependency_item_t *di;
|
|
||||||
|
|
||||||
/* Bozo check */
|
|
||||||
|
|
||||||
if (NULL == src || NULL == depend) {
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make a new depedency item */
|
|
||||||
|
|
||||||
di = OBJ_NEW(dependency_item_t);
|
|
||||||
if (NULL == di) {
|
|
||||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the new dependency item */
|
|
||||||
|
|
||||||
di->di_repository_entry = depend;
|
|
||||||
|
|
||||||
/* Add it to the dependency list on the source repository entry */
|
|
||||||
|
|
||||||
opal_list_append(&src->ri_dependencies, (opal_list_item_t *) di);
|
|
||||||
|
|
||||||
/* Increment the refcount in the dependency */
|
|
||||||
|
|
||||||
OBJ_RETAIN(depend);
|
|
||||||
|
|
||||||
/* All done */
|
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic sentinel values, and construct the inner list
|
* Basic sentinel values, and construct the inner list
|
||||||
*/
|
*/
|
||||||
static void ri_constructor(opal_object_t *obj)
|
static void ri_constructor (mca_base_component_repository_item_t *ri)
|
||||||
{
|
{
|
||||||
repository_item_t *ri = (repository_item_t *) obj;
|
|
||||||
|
|
||||||
memset(ri->ri_type, 0, sizeof(ri->ri_type));
|
memset(ri->ri_type, 0, sizeof(ri->ri_type));
|
||||||
ri->ri_dlhandle = NULL;
|
ri->ri_dlhandle = NULL;
|
||||||
ri->ri_component_struct = NULL;
|
ri->ri_component_struct = NULL;
|
||||||
|
ri->ri_path = NULL;
|
||||||
OBJ_CONSTRUCT(&ri->ri_dependencies, opal_list_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close a component
|
* Close a component
|
||||||
*/
|
*/
|
||||||
static void ri_destructor(opal_object_t *obj)
|
static void ri_destructor (mca_base_component_repository_item_t *ri)
|
||||||
{
|
{
|
||||||
repository_item_t *ri = (repository_item_t *) obj;
|
/* dlclose the component if it is still open */
|
||||||
opal_list_item_t *item;
|
mca_base_component_repository_release_internal (ri);
|
||||||
int group_id;
|
|
||||||
|
|
||||||
group_id = mca_base_var_group_find (NULL, ri->ri_type,
|
|
||||||
ri->ri_component_struct->mca_component_name);
|
|
||||||
if (0 <= group_id) {
|
|
||||||
mca_base_var_group_deregister (group_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the component (and potentially unload it from memory */
|
|
||||||
opal_dl_close(ri->ri_dlhandle);
|
|
||||||
|
|
||||||
/* It should be obvious, but I'll state it anyway because it bit me
|
/* It should be obvious, but I'll state it anyway because it bit me
|
||||||
during debugging: after the dlclose(), the mca_base_component_t
|
during debugging: after the dlclose(), the mca_base_component_t
|
||||||
pointer is no longer valid because it has [potentially] been
|
pointer is no longer valid because it has [potentially] been
|
||||||
unloaded from memory. So don't try to use it. :-) */
|
unloaded from memory. So don't try to use it. :-) */
|
||||||
|
|
||||||
/* Now go release/close (at a minimum: decrement the refcount) any
|
if (ri->ri_path) {
|
||||||
dependencies of this component */
|
free (ri->ri_path);
|
||||||
|
|
||||||
while (NULL != (item = opal_list_remove_first(&ri->ri_dependencies))) {
|
|
||||||
OBJ_RELEASE(item);
|
|
||||||
}
|
|
||||||
OBJ_DESTRUCT(&ri->ri_dependencies);
|
|
||||||
opal_list_remove_item(&repository, (opal_list_item_t *) ri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ri->ri_base) {
|
||||||
/*
|
free (ri->ri_base);
|
||||||
* Basic sentinel values
|
|
||||||
*/
|
|
||||||
static void di_constructor(opal_object_t *obj)
|
|
||||||
{
|
|
||||||
dependency_item_t *di = (dependency_item_t *) obj;
|
|
||||||
|
|
||||||
di->di_repository_entry = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When a dependency item is released, go release the repository entry
|
|
||||||
* that it points to
|
|
||||||
*/
|
|
||||||
static void di_destructor(opal_object_t *obj)
|
|
||||||
{
|
|
||||||
dependency_item_t *di = (dependency_item_t *) obj;
|
|
||||||
|
|
||||||
OBJ_RELEASE(di->di_repository_entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||||
|
@ -17,6 +17,19 @@
|
|||||||
* $HEADER$
|
* $HEADER$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file mca_base_component_repository.h
|
||||||
|
*
|
||||||
|
* This file provide the external interface to our base component
|
||||||
|
* module. Most of the components that depend on it, will use the
|
||||||
|
* retain_component() function to increase the reference count on a
|
||||||
|
* particular component (as opposed to the retain() function, which is
|
||||||
|
* internal to the opal/mca/base). But it's convenient to have all
|
||||||
|
* the functions exported from one header file rather than to separate
|
||||||
|
* retain_component() and retain() into two separate header files
|
||||||
|
* (i.e., have a separate header file just for retain()).
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef MCA_BASE_COMPONENT_REPOSITORY_H
|
#ifndef MCA_BASE_COMPONENT_REPOSITORY_H
|
||||||
#define MCA_BASE_COMPONENT_REPOSITORY_H
|
#define MCA_BASE_COMPONENT_REPOSITORY_H
|
||||||
|
|
||||||
@ -26,31 +39,71 @@
|
|||||||
#include "opal/mca/dl/base/base.h"
|
#include "opal/mca/dl/base/base.h"
|
||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
struct mca_base_component_repository_item_t {
|
||||||
|
opal_list_item_t super;
|
||||||
|
|
||||||
|
char ri_type[MCA_BASE_MAX_TYPE_NAME_LEN + 1];
|
||||||
|
char ri_name[MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
|
||||||
|
|
||||||
|
char *ri_path;
|
||||||
|
char *ri_base;
|
||||||
|
|
||||||
|
opal_dl_handle_t *ri_dlhandle;
|
||||||
|
const mca_base_component_t *ri_component_struct;
|
||||||
|
};
|
||||||
|
typedef struct mca_base_component_repository_item_t mca_base_component_repository_item_t;
|
||||||
|
|
||||||
|
OBJ_CLASS_DECLARATION(mca_base_component_repository_item_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief initialize the component repository
|
||||||
|
*
|
||||||
|
* This function must be called before any frameworks are registered or
|
||||||
|
* opened. It is responsible for setting up the repository of dynamically
|
||||||
|
* loaded components. The initial search path is taken from the
|
||||||
|
* mca_base_component_path MCA parameter. mca_base_open () is a
|
||||||
|
* prerequisite call as it registers the mca_base_component_path parameter.
|
||||||
|
*/
|
||||||
OPAL_DECLSPEC int mca_base_component_repository_init(void);
|
OPAL_DECLSPEC int mca_base_component_repository_init(void);
|
||||||
|
|
||||||
/* This file provide the external interface to our base component
|
/**
|
||||||
* module. Most of the components that depend on it, will use the
|
* @brief add search path for dynamically loaded components
|
||||||
* retain_component() function to increase the reference count on a
|
*
|
||||||
* particular component (as opposed to the retain() function, which is
|
* @param[in] path delimited list of search paths to add
|
||||||
* internal to the opal/mca/base). But it's convenient to have all
|
|
||||||
* the functions exported from one header file rather than to separate
|
|
||||||
* retain_component() and retain() into two separate header files
|
|
||||||
* (i.e., have a separate header file just for retain()).
|
|
||||||
*/
|
*/
|
||||||
OPAL_DECLSPEC int mca_base_component_repository_retain(char *type,
|
OPAL_DECLSPEC int mca_base_component_repository_add (const char *path);
|
||||||
opal_dl_handle_t *component_handle,
|
|
||||||
const mca_base_component_t *component_struct);
|
|
||||||
|
|
||||||
OPAL_DECLSPEC int mca_base_component_repository_retain_component(const char *type,
|
|
||||||
const char *name);
|
/**
|
||||||
OPAL_DECLSPEC int mca_base_component_repository_link(const char *src_type,
|
* @brief return the list of components that match a given framework
|
||||||
const char *src_name,
|
*
|
||||||
const char *depend_type,
|
* @param[in] framework framework to match
|
||||||
const char *depend_name);
|
* @param[out] framework_components components that match this framework
|
||||||
OPAL_DECLSPEC void mca_base_component_repository_release(const mca_base_component_t *component);
|
*
|
||||||
|
* The list returned in {framework_components} is owned by the component
|
||||||
|
* repository and CAN NOT be modified by the caller.
|
||||||
|
*/
|
||||||
|
OPAL_DECLSPEC int mca_base_component_repository_get_components (mca_base_framework_t *framework,
|
||||||
|
opal_list_t **framework_components);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief finalize the mca component repository
|
||||||
|
*/
|
||||||
OPAL_DECLSPEC void mca_base_component_repository_finalize(void);
|
OPAL_DECLSPEC void mca_base_component_repository_finalize(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief open the repository item and add it to the framework's component
|
||||||
|
* list
|
||||||
|
*
|
||||||
|
* @param[in] framework framework that matches the component
|
||||||
|
* @param[in] ri dynamic component to open
|
||||||
|
*/
|
||||||
|
int mca_base_component_repository_open (mca_base_framework_t *framework,
|
||||||
|
mca_base_component_repository_item_t *ri);
|
||||||
|
|
||||||
|
|
||||||
|
void mca_base_component_repository_release(const mca_base_component_t *component);
|
||||||
|
|
||||||
END_C_DECLS
|
END_C_DECLS
|
||||||
|
|
||||||
#endif /* MCA_BASE_COMPONENT_REPOSITORY_H */
|
#endif /* MCA_BASE_COMPONENT_REPOSITORY_H */
|
||||||
|
@ -44,7 +44,7 @@ void mca_base_component_unload (const mca_base_component_t *component, int outpu
|
|||||||
mca_base_var_group_deregister (ret);
|
mca_base_var_group_deregister (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
mca_base_component_repository_release((mca_base_component_t *) component);
|
mca_base_component_repository_release (component);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mca_base_component_close (const mca_base_component_t *component, int output_id)
|
void mca_base_component_close (const mca_base_component_t *component, int output_id)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* 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) 2008-2012 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2011-2013 Los Alamos National Security, LLC.
|
* Copyright (c) 2011-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2014 Hochschule Esslingen. All rights reserved.
|
* Copyright (c) 2014 Hochschule Esslingen. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
@ -56,11 +56,9 @@ int mca_base_framework_components_open (mca_base_framework_t *framework,
|
|||||||
{
|
{
|
||||||
/* Open flags are not used at this time. Suppress compiler warning. */
|
/* Open flags are not used at this time. Suppress compiler warning. */
|
||||||
if (flags & MCA_BASE_OPEN_FIND_COMPONENTS) {
|
if (flags & MCA_BASE_OPEN_FIND_COMPONENTS) {
|
||||||
|
bool open_dso_components = !(flags & MCA_BASE_OPEN_STATIC_ONLY);
|
||||||
/* Find and load requested components */
|
/* Find and load requested components */
|
||||||
int ret = mca_base_component_find(NULL, framework->framework_name,
|
int ret = mca_base_component_find(NULL, framework, false, open_dso_components);
|
||||||
framework->framework_static_components,
|
|
||||||
framework->framework_selection,
|
|
||||||
&framework->framework_components, true);
|
|
||||||
if (OPAL_SUCCESS != ret) {
|
if (OPAL_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -70,53 +68,6 @@ int mca_base_framework_components_open (mca_base_framework_t *framework,
|
|||||||
return open_components (framework);
|
return open_components (framework);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mca_base_components_open (const char *type_name, int output_id,
|
|
||||||
const mca_base_component_t **static_components,
|
|
||||||
opal_list_t *components_available,
|
|
||||||
bool open_dso_components)
|
|
||||||
{
|
|
||||||
/* create a dummy framework -- this leaks -- i know -- but it is temporary */
|
|
||||||
mca_base_register_flag_t register_flags;
|
|
||||||
mca_base_framework_t *dummy_framework;
|
|
||||||
opal_list_item_t *item;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
dummy_framework = calloc (1, sizeof(*dummy_framework));
|
|
||||||
|
|
||||||
dummy_framework->framework_static_components = static_components;
|
|
||||||
dummy_framework->framework_output = output_id;
|
|
||||||
dummy_framework->framework_name = strdup(type_name);
|
|
||||||
|
|
||||||
if (open_dso_components) {
|
|
||||||
register_flags = MCA_BASE_REGISTER_STATIC_ONLY;
|
|
||||||
} else {
|
|
||||||
register_flags = MCA_BASE_REGISTER_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mca_base_framework_components_register (dummy_framework, register_flags);
|
|
||||||
if (OPAL_SUCCESS != ret) {
|
|
||||||
free (dummy_framework);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mca_base_framework_components_open (dummy_framework, 0);
|
|
||||||
if (OPAL_SUCCESS != ret) {
|
|
||||||
(void) mca_base_framework_components_close (dummy_framework, NULL);
|
|
||||||
free (dummy_framework);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
OBJ_CONSTRUCT(components_available, opal_list_t);
|
|
||||||
|
|
||||||
while (NULL != (item = opal_list_remove_first(&dummy_framework->framework_components))) {
|
|
||||||
opal_list_append(components_available, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
OBJ_DESTRUCT(&dummy_framework->framework_components);
|
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Traverse the entire list of found components (a list of
|
* Traverse the entire list of found components (a list of
|
||||||
* mca_base_component_t instances). If the requested_component_names
|
* mca_base_component_t instances). If the requested_component_names
|
||||||
@ -152,16 +103,13 @@ static int open_components(mca_base_framework_t *framework)
|
|||||||
|
|
||||||
/* If mca_base_framework_register_components was called with the MCA_BASE_COMPONENTS_ALL flag
|
/* If mca_base_framework_register_components was called with the MCA_BASE_COMPONENTS_ALL flag
|
||||||
we need to trim down and close any extra components we do not want open */
|
we need to trim down and close any extra components we do not want open */
|
||||||
ret = mca_base_components_filter (framework->framework_name, &framework->framework_components,
|
ret = mca_base_components_filter (framework, open_only_flags);
|
||||||
framework->framework_output, framework->framework_selection,
|
|
||||||
open_only_flags);
|
|
||||||
if (OPAL_SUCCESS != ret) {
|
if (OPAL_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Announce */
|
/* Announce */
|
||||||
opal_output_verbose(10, output_id,
|
opal_output_verbose(10, output_id, "mca: base: components_open: opening %s components",
|
||||||
"mca: base: components_open: opening %s components",
|
|
||||||
framework->framework_name);
|
framework->framework_name);
|
||||||
|
|
||||||
/* Traverse the list of components */
|
/* Traverse the list of components */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* 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) 2008-2012 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2011-2013 Los Alamos National Security, LLC.
|
* Copyright (c) 2011-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
@ -39,8 +39,7 @@
|
|||||||
/*
|
/*
|
||||||
* Local functions
|
* Local functions
|
||||||
*/
|
*/
|
||||||
static int register_components(const char *project_name, const char *type_name,
|
static int register_components(mca_base_framework_t *framework);
|
||||||
int output_id, opal_list_t *src, opal_list_t *dest);
|
|
||||||
/**
|
/**
|
||||||
* Function for finding and opening either all MCA components, or the
|
* Function for finding and opening either all MCA components, or the
|
||||||
* one that was specifically requested via a MCA parameter.
|
* one that was specifically requested via a MCA parameter.
|
||||||
@ -50,28 +49,16 @@ int mca_base_framework_components_register (mca_base_framework_t *framework,
|
|||||||
{
|
{
|
||||||
bool open_dso_components = !(flags & MCA_BASE_REGISTER_STATIC_ONLY);
|
bool open_dso_components = !(flags & MCA_BASE_REGISTER_STATIC_ONLY);
|
||||||
bool ignore_requested = !!(flags & MCA_BASE_REGISTER_ALL);
|
bool ignore_requested = !!(flags & MCA_BASE_REGISTER_ALL);
|
||||||
opal_list_t components_found;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Find and load requested components */
|
/* Find and load requested components */
|
||||||
ret = mca_base_component_find(NULL, framework->framework_name,
|
ret = mca_base_component_find(NULL, framework, ignore_requested, open_dso_components);
|
||||||
framework->framework_static_components,
|
|
||||||
ignore_requested ? NULL : framework->framework_selection,
|
|
||||||
&components_found, open_dso_components);
|
|
||||||
|
|
||||||
if (OPAL_SUCCESS != ret) {
|
if (OPAL_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register all remaining components */
|
/* Register all remaining components */
|
||||||
ret = register_components(framework->framework_project, framework->framework_name,
|
return register_components(framework);
|
||||||
framework->framework_output, &components_found,
|
|
||||||
&framework->framework_components);
|
|
||||||
|
|
||||||
OBJ_DESTRUCT(&components_found);
|
|
||||||
|
|
||||||
/* All done */
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,24 +68,21 @@ int mca_base_framework_components_register (mca_base_framework_t *framework,
|
|||||||
* components is in the requested_components_array, try to open it.
|
* components is in the requested_components_array, try to open it.
|
||||||
* If it opens, add it to the components_available list.
|
* If it opens, add it to the components_available list.
|
||||||
*/
|
*/
|
||||||
static int register_components(const char *project_name, const char *type_name,
|
static int register_components(mca_base_framework_t *framework)
|
||||||
int output_id, opal_list_t *src, opal_list_t *dest)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
opal_list_item_t *item;
|
|
||||||
mca_base_component_t *component;
|
mca_base_component_t *component;
|
||||||
mca_base_component_list_item_t *cli;
|
mca_base_component_list_item_t *cli, *next;
|
||||||
|
int output_id = framework->framework_output;
|
||||||
|
|
||||||
/* Announce */
|
/* Announce */
|
||||||
opal_output_verbose(10, output_id,
|
opal_output_verbose(10, output_id,
|
||||||
"mca: base: components_register: registering %s components",
|
"mca: base: components_register: registering framework %s components",
|
||||||
type_name);
|
framework->framework_name);
|
||||||
|
|
||||||
/* Traverse the list of found components */
|
/* Traverse the list of found components */
|
||||||
|
|
||||||
OBJ_CONSTRUCT(dest, opal_list_t);
|
OPAL_LIST_FOREACH_SAFE(cli, next, &framework->framework_components, mca_base_component_list_item_t) {
|
||||||
while (NULL != (item = opal_list_remove_first (src))) {
|
|
||||||
cli = (mca_base_component_list_item_t *) item;
|
|
||||||
component = (mca_base_component_t *)cli->cli_component;
|
component = (mca_base_component_t *)cli->cli_component;
|
||||||
|
|
||||||
opal_output_verbose(10, output_id,
|
opal_output_verbose(10, output_id,
|
||||||
@ -142,7 +126,7 @@ static int register_components(const char *project_name, const char *type_name,
|
|||||||
component->mca_component_name);
|
component->mca_component_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
mca_base_component_unload (component, output_id);
|
opal_list_remove_item (&framework->framework_components, &cli->super);
|
||||||
|
|
||||||
/* Release this list item */
|
/* Release this list item */
|
||||||
OBJ_RELEASE(cli);
|
OBJ_RELEASE(cli);
|
||||||
@ -168,8 +152,6 @@ static int register_components(const char *project_name, const char *type_name,
|
|||||||
0, MCA_BASE_VAR_FLAG_DEFAULT_ONLY | MCA_BASE_VAR_FLAG_INTERNAL,
|
0, MCA_BASE_VAR_FLAG_DEFAULT_ONLY | MCA_BASE_VAR_FLAG_INTERNAL,
|
||||||
OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_CONSTANT,
|
OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_CONSTANT,
|
||||||
&component->mca_component_release_version);
|
&component->mca_component_release_version);
|
||||||
|
|
||||||
opal_list_append(dest, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All done */
|
/* All done */
|
||||||
|
@ -65,6 +65,8 @@ int mca_base_framework_register (struct mca_base_framework_t *framework,
|
|||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OBJ_CONSTRUCT(&framework->framework_components, opal_list_t);
|
||||||
|
|
||||||
if (framework->framework_flags & MCA_BASE_FRAMEWORK_FLAG_NO_DSO) {
|
if (framework->framework_flags & MCA_BASE_FRAMEWORK_FLAG_NO_DSO) {
|
||||||
flags |= MCA_BASE_REGISTER_STATIC_ONLY;
|
flags |= MCA_BASE_REGISTER_STATIC_ONLY;
|
||||||
}
|
}
|
||||||
@ -147,6 +149,10 @@ int mca_base_framework_open (struct mca_base_framework_t *framework,
|
|||||||
|
|
||||||
if (MCA_BASE_FRAMEWORK_FLAG_NOREGISTER & framework->framework_flags) {
|
if (MCA_BASE_FRAMEWORK_FLAG_NOREGISTER & framework->framework_flags) {
|
||||||
flags |= MCA_BASE_OPEN_FIND_COMPONENTS;
|
flags |= MCA_BASE_OPEN_FIND_COMPONENTS;
|
||||||
|
|
||||||
|
if (MCA_BASE_FRAMEWORK_FLAG_NO_DSO & framework->framework_flags) {
|
||||||
|
flags |= MCA_BASE_OPEN_STATIC_ONLY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lock all of this frameworks's variables */
|
/* lock all of this frameworks's variables */
|
||||||
@ -221,6 +227,8 @@ int mca_base_framework_close (struct mca_base_framework_t *framework) {
|
|||||||
|
|
||||||
framework->framework_flags &= ~(MCA_BASE_FRAMEWORK_FLAG_REGISTERED | MCA_BASE_FRAMEWORK_FLAG_OPEN);
|
framework->framework_flags &= ~(MCA_BASE_FRAMEWORK_FLAG_REGISTERED | MCA_BASE_FRAMEWORK_FLAG_OPEN);
|
||||||
|
|
||||||
|
OBJ_DESTRUCT(&framework->framework_components);
|
||||||
|
|
||||||
framework_close_output (framework);
|
framework_close_output (framework);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -33,7 +33,9 @@ enum mca_base_open_flag_t {
|
|||||||
/** Find components in mca_base_components_find. Used by
|
/** Find components in mca_base_components_find. Used by
|
||||||
mca_base_framework_open() when NOREGISTER is specified
|
mca_base_framework_open() when NOREGISTER is specified
|
||||||
by the framework */
|
by the framework */
|
||||||
MCA_BASE_OPEN_FIND_COMPONENTS = 1
|
MCA_BASE_OPEN_FIND_COMPONENTS = 1,
|
||||||
|
/** Do not open DSO components */
|
||||||
|
MCA_BASE_OPEN_STATIC_ONLY = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum mca_base_open_flag_t mca_base_open_flag_t;
|
typedef enum mca_base_open_flag_t mca_base_open_flag_t;
|
||||||
|
@ -172,4 +172,4 @@ opal_installdirs_base_close(void)
|
|||||||
/* Declare the installdirs framework */
|
/* Declare the installdirs framework */
|
||||||
MCA_BASE_FRAMEWORK_DECLARE(opal, installdirs, NULL, NULL, opal_installdirs_base_open,
|
MCA_BASE_FRAMEWORK_DECLARE(opal, installdirs, NULL, NULL, opal_installdirs_base_open,
|
||||||
opal_installdirs_base_close, mca_installdirs_base_static_components,
|
opal_installdirs_base_close, mca_installdirs_base_static_components,
|
||||||
MCA_BASE_FRAMEWORK_FLAG_NOREGISTER);
|
MCA_BASE_FRAMEWORK_FLAG_NOREGISTER | MCA_BASE_FRAMEWORK_FLAG_NO_DSO);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* 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) 2008-2015 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2010-2013 Los Alamos National Security, LLC.
|
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
@ -163,9 +163,6 @@ opal_finalize(void)
|
|||||||
/* close the sec framework */
|
/* close the sec framework */
|
||||||
(void) mca_base_framework_close(&opal_sec_base_framework);
|
(void) mca_base_framework_close(&opal_sec_base_framework);
|
||||||
|
|
||||||
/* finalize the mca */
|
|
||||||
mca_base_close();
|
|
||||||
|
|
||||||
/* finalize util code */
|
/* finalize util code */
|
||||||
opal_finalize_util();
|
opal_finalize_util();
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Copyright (c) 2007-2012 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2007-2012 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
|
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
|
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
|
||||||
* Copyright (c) 2010-2013 Los Alamos National Security, LLC.
|
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2013-2014 Intel, Inc. All rights reserved
|
* Copyright (c) 2013-2014 Intel, Inc. All rights reserved
|
||||||
* Copyright (c) 2015 Research Organization for Information Science
|
* Copyright (c) 2015 Research Organization for Information Science
|
||||||
@ -354,6 +354,12 @@ opal_init_util(int* pargc, char*** pargv)
|
|||||||
goto return_error;
|
goto return_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize the mca */
|
||||||
|
if (OPAL_SUCCESS != (ret = mca_base_open())) {
|
||||||
|
error = "mca_base_open";
|
||||||
|
goto return_error;
|
||||||
|
}
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
|
|
||||||
return_error:
|
return_error:
|
||||||
@ -384,12 +390,6 @@ opal_init(int* pargc, char*** pargv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the mca */
|
|
||||||
if (OPAL_SUCCESS != (ret = mca_base_open())) {
|
|
||||||
error = "mca_base_open";
|
|
||||||
goto return_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open hwloc - since this is a static framework, no
|
/* open hwloc - since this is a static framework, no
|
||||||
* select is required
|
* select is required
|
||||||
*/
|
*/
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user