/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality (vs. ltdl's * lt_dladdsearchdir() functionality) because we need to look at * companion .ompi_info files in the same directory as the library to * generate dependencies, etc. If we use the plain lt_dlopen() * functionality, we would not get the directory name of the file * finally opened in recursive dependency traversals. */ static void find_dyn_components(const char *path, const char *type_name, const char **names, bool include_mode, opal_list_t *found_components) { int i, len; char *path_to_use = NULL, *dir, *end; component_file_item_t *file; opal_list_item_t *cur; char prefix[32 + MCA_BASE_MAX_TYPE_NAME_LEN], *basename; /* If path is NULL, iterate over the set of directories specified by the MCA param mca_base_component_path. If path is not NULL, then use that as the path. */ if (NULL == path) { if (NULL != mca_base_component_path) { path_to_use = strdup (mca_base_component_path); } else { /* If there's no path, then there's nothing to search -- we're done */ return; } if (NULL == path_to_use) { /* out of memory */ return; } } else { path_to_use = strdup(path); } /* If we haven't done so already, iterate over all the files in the directories in the path and make a master array of all the matching filenames that we find. Save the filenames in an argv-style array. Re-scan do this if the mca_component_path has changed. */ if (NULL == found_filenames || (NULL != last_path_to_use && 0 != strcmp(path_to_use, last_path_to_use))) { if (NULL != found_filenames) { opal_argv_free(found_filenames); found_filenames = NULL; free(last_path_to_use); last_path_to_use = NULL; } if (NULL == last_path_to_use) { last_path_to_use = strdup(path_to_use); } dir = path_to_use; if (NULL != dir) { do { end = strchr(dir, OPAL_ENV_SEP); if (NULL != end) { *end = '\0'; } if ((0 == strcmp(dir, "USER_DEFAULT") || 0 == strcmp(dir, "USR_DEFAULT")) && NULL != mca_base_user_default_path) { if (0 != lt_dlforeachfile(mca_base_user_default_path, save_filename, NULL)) { break; } } else if (0 == strcmp(dir, "SYS_DEFAULT") || 0 == strcmp(dir, "SYSTEM_DEFAULT")) { if (0 != lt_dlforeachfile(mca_base_system_default_path, save_filename, NULL)) { break; } } else { if (0 != lt_dlforeachfile(dir, save_filename, NULL)) { break; } } dir = end + 1; } while (NULL != end); } } /* Look through the list of found files and find those that match the desired framework name */ snprintf(prefix, sizeof(prefix) - 1, component_template, type_name); len = strlen(prefix); OBJ_CONSTRUCT(&found_files, opal_list_t); for (i = 0; NULL != found_filenames && NULL != found_filenames[i]; ++i) { basename = strrchr(found_filenames[i], '/'); if (NULL == basename) { basename = found_filenames[i]; } else { basename += 1; } if (0 != strncmp(basename, prefix, len)) { continue; } /* We found a match; save all the relevant details in the found_files list */ file = OBJ_NEW(component_file_item_t); if (NULL == file) { return; } strncpy(file->type, type_name, MCA_BASE_MAX_TYPE_NAME_LEN); file->type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; strncpy(file->name, basename + len, MCA_BASE_MAX_COMPONENT_NAME_LEN); file->name[MCA_BASE_MAX_COMPONENT_NAME_LEN] = '\0'; strncpy(file->basename, basename, OPAL_PATH_MAX); file->basename[OPAL_PATH_MAX] = '\0'; strncpy(file->filename, found_filenames[i], OPAL_PATH_MAX); file->filename[OPAL_PATH_MAX] = '\0'; file->status = UNVISITED; opal_list_append(&found_files, (opal_list_item_t *) file); } /* Iterate through all the filenames that we found that matched the framework we were looking for. Since one component may [try to] call another to be loaded, only try to load the UNVISITED files. Also, ignore the return code -- basically, give every file one chance to try to load. If they load, great. If not, great. */ for (cur = opal_list_get_first(&found_files); opal_list_get_end(&found_files) != cur; cur = opal_list_get_next(cur)) { file = (component_file_item_t *) cur; if( UNVISITED == file->status ) { bool op = true; file->status = CHECKING_CYCLE; op = use_component(include_mode, names, file->name); if( true == op ) { open_component(file, found_components); } } } /* So now we have a final list of loaded components. We can free all the file information. */ for (cur = opal_list_remove_first(&found_files); NULL != cur; cur = opal_list_remove_first(&found_files)) { OBJ_RELEASE(cur); } OBJ_DESTRUCT(&found_files); /* All done, now let's cleanup */ free(path_to_use); }
/* * 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; 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); strcat(buffer, name); /* 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)", NULL); 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, NULL); 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, NULL); 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, NULL); 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, NULL); 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, NULL); } 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; }
/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality (vs. ltdl's * lt_dladdsearchdir() functionality) because we need to look at * companion .ompi_info files in the same directory as the library to * generate dependencies, etc. If we use the plain lt_dlopen() * functionality, we would not get the directory name of the file * finally opened in recursive dependency traversals. */ static void find_dyn_components(const char *path, const char *type_name, const char **name, bool include_mode, opal_list_t *found_components) { ltfn_data_holder_t params; char *path_to_use, *dir, *end; component_file_item_t *file; opal_list_item_t *cur; strncpy(params.type, type_name, MCA_BASE_MAX_TYPE_NAME_LEN); params.type[MCA_BASE_MAX_TYPE_NAME_LEN] = '\0'; params.name[0] = '\0'; /* If path is NULL, iterate over the set of directories specified by the MCA param mca_base_component_path. If path is not NULL, then use that as the path. */ if (NULL == path) { mca_base_param_lookup_string(mca_base_param_component_path, &path_to_use); if (NULL == path_to_use) { /* If there's no path, then there's nothing to search -- we're done */ return; } } else { path_to_use = strdup(path); } /* Iterate over all the files in the directories in the path and make a master array of all the matching filenames that we find. */ OBJ_CONSTRUCT(&found_files, opal_list_t); dir = path_to_use; if (NULL != dir) { do { end = strchr(dir, OPAL_ENV_SEP); if (NULL != end) { *end = '\0'; } if (0 != lt_dlforeachfile(dir, save_filename, ¶ms)) { break; } dir = end + 1; } while (NULL != end); } /* Iterate through all the filenames that we found. Since one component may [try to] call another to be loaded, only try to load the UNVISITED files. Also, ignore the return code -- basically, give every file one chance to try to load. If they load, great. If not, great. */ for (cur = opal_list_get_first(&found_files); opal_list_get_end(&found_files) != cur; cur = opal_list_get_next(cur)) { file = (component_file_item_t *) cur; if( UNVISITED == file->status ) { bool op = true; file->status = CHECKING_CYCLE; op = use_component(include_mode, name, file->name); if( true == op ) { open_component(file, found_components); } } } /* So now we have a final list of loaded components. We can free all the file information. */ for (cur = opal_list_remove_first(&found_files); NULL != cur; cur = opal_list_remove_first(&found_files)) { OBJ_RELEASE(cur); } /* All done, now let's cleanup */ free(path_to_use); OBJ_DESTRUCT(&found_files); }
/* * Open up all directories in a given path and search for components of * the specified type (and possibly of a given name). * * Note that we use our own path iteration functionality (vs. ltdl's * lt_dladdsearchdir() functionality) because we need to look at * companion .ompi_info files in the same directory as the library to * generate dependencies, etc. If we use the plain lt_dlopen() * functionality, we would not get the directory name of the file * finally opened in recursive dependency traversals. */ static void find_dyn_components(const char *path, const char *type_name, const char *name, opal_list_t *found_components) { ltfn_data_holder_t params; char *path_to_use, *dir, *end, *param; component_file_item_t *file; opal_list_item_t *cur; strcpy(params.type, type_name); if (NULL == name) { params.name[0] = '\0'; opal_output_verbose(40, 0, "mca: base: component_find: looking for all dynamic %s MCA components", type_name, NULL); } else { strcpy(params.name, name); opal_output_verbose(40, 0, "mca: base: component_find: looking for dynamic %s MCA component named \"%s\"", type_name, name, NULL); } /* If path is NULL, iterate over the set of directories specified by the MCA param mca_base_component_path. If path is not NULL, then use that as the path. */ param = NULL; if (NULL == path) { mca_base_param_lookup_string(mca_base_param_component_path, ¶m); if (NULL == param) { /* If there's no path, then there's nothing to search -- we're done */ return; } else { path_to_use = strdup(param); } } else { path_to_use = strdup(path); } /* Iterate over all the files in the directories in the path and make a master array of all the matching filenames that we find. */ OBJ_CONSTRUCT(&found_files, opal_list_t); dir = path_to_use; if (NULL != dir) { do { end = strchr(dir, OPAL_ENV_SEP); if (NULL != end) { *end = '\0'; } if (0 != lt_dlforeachfile(dir, save_filename, ¶ms)) { break; } dir = end + 1; } while (NULL != end); } /* Iterate through all the filenames that we found. Since one component may [try to] call another to be loaded, only try to load the UNVISITED files. Also, ignore the return code -- basically, give every file one chance to try to load. If they load, great. If not, great. */ for (cur = opal_list_get_first(&found_files); opal_list_get_end(&found_files) != cur; cur = opal_list_get_next(cur)) { file = (component_file_item_t *) cur; if (UNVISITED == file->status) { open_component(file, found_components); } } /* So now we have a final list of loaded components. We can free all the file information. */ for (cur = opal_list_remove_first(&found_files); NULL != cur; cur = opal_list_remove_first(&found_files)) { OBJ_RELEASE(cur); } /* All done */ if (NULL != param) { free(param); } if (NULL != path_to_use) { free(path_to_use); } OBJ_DESTRUCT(&found_files); }