📄 mca_base_component_find.c
字号:
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)", NULL); target_file->status = FAILED_TO_LOAD; return OPAL_ERR_BAD_PARAM; } } /* Look at see if this component has any dependencies. If so, load them. If we can't load them, then this component must also fail to load. */ OBJ_CONSTRUCT(&dependencies, opal_list_t); if (0 != check_ompi_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 */ component_handle = lt_dlopenext(target_file->filename); if (NULL == component_handle) { err = strdup(lt_dlerror()); if (0 != show_errors) { opal_output(0, "mca: base: component_find: unable to open %s %s: %s (ignored)", target_file->type, target_file->name, err); } opal_output_verbose(40, 0, "mca: base: component_find: unable to open %s: %s (ignored)", target_file->filename, err, NULL); free(err); 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) { lt_dlclose(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); lt_dlclose(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_OUT_OF_RESOURCE; } component_struct = (mca_base_component_t*)lt_dlsym(component_handle, struct_name); if (NULL == component_struct) { if (0 != show_errors) { opal_output(0, "mca: base: component_find: \"%s\" does not appear to be a valid " "%s MCA dynamic component (ignored)", target_file->basename, target_file->type, NULL); } opal_output_verbose(40, 0, "mca: base: component_find: \"%s\" does not appear to be a valid " "%s MCA dynamic component (ignored)", target_file->basename, target_file->type, NULL); free(mitem); free(struct_name); lt_dlclose(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_BAD_PARAM; } /* We found the public struct. Save it, 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, NULL); 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_ompi_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(ompi_info_suffix) + 16; depname = (char*)malloc(len); if (NULL == depname) return OPAL_ERR_OUT_OF_RESOURCE; snprintf(depname, len, "%s%s", target_file->filename, ompi_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, NULL); 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, NULL); /* 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; 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;}/* * 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 /* OMPI_WANT_LIBLTDL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -