From a9d86129c6a4f0843f4e405b6d2d3a9e0c8e7c20 Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Wed, 18 Feb 2015 10:24:10 -0800 Subject: [PATCH] mca base: convert to opal_dl interface --- opal/mca/base/mca_base_component_find.c | 110 ++++++++---------- opal/mca/base/mca_base_component_repository.c | 93 +++++++-------- opal/mca/base/mca_base_component_repository.h | 34 +----- 3 files changed, 90 insertions(+), 147 deletions(-) diff --git a/opal/mca/base/mca_base_component_find.c b/opal/mca/base/mca_base_component_find.c index 19f0961fb0..a1e7f1b928 100644 --- a/opal/mca/base/mca_base_component_find.c +++ b/opal/mca/base/mca_base_component_find.c @@ -10,7 +10,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2008-2010 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. @@ -43,14 +43,6 @@ #include #endif -#if OPAL_WANT_LIBLTDL - #if OPAL_LIBLTDL_INTERNAL - #include "opal/libltdl/ltdl.h" - #else - #include "ltdl.h" - #endif -#endif - #include "opal/mca/installdirs/installdirs.h" #include "opal/util/opal_environ.h" #include "opal/util/output.h" @@ -61,9 +53,10 @@ #include "opal/mca/base/base.h" #include "opal/mca/base/mca_base_component_repository.h" #include "opal/constants.h" +#include "opal/mca/dl/base/base.h" -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT /* * Private types; only necessary when we're dlopening components. */ @@ -98,20 +91,17 @@ typedef struct dependency_item_t dependency_item_t; static OBJ_CLASS_INSTANCE(dependency_item_t, opal_list_item_t, NULL, NULL); -#if OPAL_HAVE_LTDL_ADVISE -extern lt_dladvise opal_mca_dladvise; -#endif -#endif /* OPAL_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT /* * Private functions */ static void find_dyn_components(const char *path, const char *type, const char **names, bool include_mode, opal_list_t *found_components); -static int save_filename(const char *filename, lt_ptr data); +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, @@ -131,7 +121,7 @@ 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_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ static int component_find_check (const char *framework_name, char **requested_component_names, opal_list_t *components); @@ -196,7 +186,7 @@ int mca_base_component_find(const char *directory, const char *type, } } -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT /* Find any available dynamic components in the specified directory */ if (open_dso_components && !mca_base_component_disable_dlopen) { find_dyn_components(directory, type, @@ -228,7 +218,7 @@ component_find_out: int mca_base_component_find_finalize(void) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT if (NULL != found_filenames) { opal_argv_free(found_filenames); found_filenames = NULL; @@ -306,18 +296,15 @@ int mca_base_components_filter (const char *framework_name, opal_list_t *compone return ret; } -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT /* * 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. + * Note that we use our own path iteration functionality because we + * need to look at companion .ompi_info files in the same directory as + * the library to generate dependencies, etc. */ static void find_dyn_components(const char *path, const char *type_name, const char **names, bool include_mode, @@ -377,18 +364,18 @@ static void find_dyn_components(const char *path, const char *type_name, 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)) { + 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 != lt_dlforeachfile(mca_base_system_default_path, - save_filename, NULL)) { + if (0 != opal_dl_foreachfile(mca_base_system_default_path, + save_filename, NULL)) { break; } } else { - if (0 != lt_dlforeachfile(dir, save_filename, NULL)) { + if (0 != opal_dl_foreachfile(dir, save_filename, NULL)) { break; } } @@ -475,7 +462,7 @@ static void find_dyn_components(const char *path, const char *type_name, * Blindly save all filenames into an argv-style list. This function * is the callback from lt_dlforeachfile(). */ -static int save_filename(const char *filename, lt_ptr data) +static int save_filename(const char *filename, void *data) { opal_argv_append_nosize(&found_filenames, filename); return 0; @@ -508,9 +495,9 @@ static int file_exists(const char *filename, const char *ext) static int open_component(component_file_item_t *target_file, opal_list_t *found_components) { - lt_dlhandle component_handle; + opal_dl_handle_t *component_handle; mca_base_component_t *component_struct; - char *struct_name, *err; + char *struct_name; opal_list_t dependencies; opal_list_item_t *cur; mca_base_component_list_item_t *mitem; @@ -562,18 +549,14 @@ static int open_component(component_file_item_t *target_file, /* Now try to load the component */ -#if OPAL_HAVE_LTDL_ADVISE - component_handle = lt_dlopenadvise(target_file->filename, opal_mca_dladvise); -#else - component_handle = lt_dlopenext(target_file->filename); -#endif - if (NULL == component_handle) { - /* Apparently lt_dlerror() sometimes returns NULL! */ - const char *str = lt_dlerror(); - if (NULL != str) { - err = strdup(str); + char *err_msg; + if (OPAL_SUCCESS != + opal_dl_open(target_file->filename, true, false, &component_handle, + &err_msg)) { + if (NULL != err_msg) { + err_msg = strdup(err_msg); } else { - err = strdup("lt_dlerror() returned NULL!"); + 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 @@ -581,17 +564,17 @@ static int open_component(component_file_item_t *target_file, (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) && + 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); - err = strdup("perhaps a missing symbol, or compiled for a different version of Open MPI?"); + 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); - free(err); + target_file->filename, err_msg); + free(err_msg); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_BAD_PARAM; @@ -603,7 +586,7 @@ static int open_component(component_file_item_t *target_file, len = strlen(target_file->type) + strlen(target_file->name) + 32; struct_name = (char*)malloc(len); if (NULL == struct_name) { - lt_dlclose(component_handle); + opal_dl_close(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_OUT_OF_RESOURCE; @@ -614,25 +597,24 @@ static int open_component(component_file_item_t *target_file, mitem = OBJ_NEW(mca_base_component_list_item_t); if (NULL == mitem) { free(struct_name); - lt_dlclose(component_handle); + opal_dl_close(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) { - /* Apparently lt_dlerror() sometimes returns NULL! */ - const char *str = lt_dlerror(); - if (NULL == str) { - str = "lt_dlerror() returned NULL!"; + 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, str); + "%s MCA dynamic component (ignored): %s", + target_file->basename, target_file->type, err_msg); free(mitem); free(struct_name); - lt_dlclose(component_handle); + opal_dl_close(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_BAD_PARAM; @@ -652,7 +634,7 @@ static int open_component(component_file_item_t *target_file, MCA_BASE_VERSION_RELEASE); free(mitem); free(struct_name); - lt_dlclose(component_handle); + opal_dl_close(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_BAD_PARAM; @@ -668,7 +650,7 @@ static int open_component(component_file_item_t *target_file, component_struct->mca_component_name); free(mitem); free(struct_name); - lt_dlclose(component_handle); + opal_dl_close(component_handle); target_file->status = FAILED_TO_LOAD; free_dependency_list(&dependencies); return OPAL_ERR_BAD_PARAM; @@ -945,7 +927,7 @@ static void free_dependency_list(opal_list_t *dependencies) OBJ_DESTRUCT(dependencies); } -#endif /* OPAL_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ static bool use_component(const bool include_mode, const char **requested_component_names, diff --git a/opal/mca/base/mca_base_component_repository.c b/opal/mca/base/mca_base_component_repository.c index ea1108d400..35ba4e6a76 100644 --- a/opal/mca/base/mca_base_component_repository.c +++ b/opal/mca/base/mca_base_component_repository.c @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2008-2010 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -26,21 +26,14 @@ #include #include -#if OPAL_WANT_LIBLTDL - #if OPAL_LIBLTDL_INTERNAL - #include "opal/libltdl/ltdl.h" - #else - #include "ltdl.h" - #endif -#endif - #include "opal/class/opal_list.h" #include "opal/mca/mca.h" #include "opal/mca/base/base.h" #include "opal/mca/base/mca_base_component_repository.h" +#include "opal/mca/dl/base/base.h" #include "opal/constants.h" -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT /* * Private types @@ -49,7 +42,7 @@ struct repository_item_t { opal_list_item_t super; char ri_type[MCA_BASE_MAX_TYPE_NAME_LEN + 1]; - lt_dlhandle ri_dlhandle; + opal_dl_handle_t *ri_dlhandle; const mca_base_component_t *ri_component_struct; opal_list_t ri_dependencies; }; @@ -70,7 +63,7 @@ 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_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ /* @@ -79,7 +72,7 @@ static OBJ_CLASS_INSTANCE(dependency_item_t, opal_list_item_t, static bool initialized = false; -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT static opal_list_t repository; @@ -90,11 +83,7 @@ static opal_list_t repository; static repository_item_t *find_component(const char *type, const char *name); static int link_items(repository_item_t *src, repository_item_t *depend); -#if OPAL_HAVE_LTDL_ADVISE -lt_dladvise opal_mca_dladvise; -#endif - -#endif /* OPAL_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ /* @@ -105,29 +94,30 @@ int mca_base_component_repository_init(void) /* Setup internal structures */ if (!initialized) { -#if OPAL_WANT_LIBLTDL - /* Initialize libltdl */ +#if OPAL_HAVE_DL_SUPPORT - if (lt_dlinit() != 0) { - return OPAL_ERR_OUT_OF_RESOURCE; + /* Initialize the dl framework */ + int ret = mca_base_framework_open(&opal_dl_base_framework, 0); + if (OPAL_SUCCESS != ret) { + opal_output(0, "%s %d:%s failed -- process will likely abort (open the dl framework returned %d instead of OPAL_SUCCESS)\n", + __FILE__, __LINE__, __func__, ret); + return ret; } + opal_dl_base_select(); -#if OPAL_HAVE_LTDL_ADVISE - if (lt_dladvise_init(&opal_mca_dladvise)) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - - if (lt_dladvise_ext(&opal_mca_dladvise)) { - return OPAL_ERROR; - } - - if (lt_dladvise_global(&opal_mca_dladvise)) { - return OPAL_ERROR; - } -#endif + /* Bump the refcount to indicate that this framework is "special" + -- it can't be finalized until all other frameworks have been + finalized. E.g., in opal/runtime/opal_info_support.c, there's + a loop calling mca_base_framework_close() on all OPAL + frameworks. But that function simply decrements each + framework's refcount, and if it's zero, closes it. This + additional increment ensures that the "dl" framework is not + closed as part of that loop. */ + ++opal_dl_base_framework.framework_refcnt; OBJ_CONSTRUCT(&repository, opal_list_t); #endif + initialized = true; } @@ -143,10 +133,10 @@ int mca_base_component_repository_init(void) * saved. */ int mca_base_component_repository_retain(char *type, - lt_dlhandle component_handle, + opal_dl_handle_t *component_handle, const mca_base_component_t *component_struct) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT repository_item_t *ri; /* Allocate a new repository item */ @@ -182,7 +172,7 @@ int mca_base_component_repository_retain(char *type, int mca_base_component_repository_retain_component(const char *type, const char *name) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT repository_item_t *ri = find_component(type, name); if (NULL != ri) { OBJ_RETAIN(ri); @@ -203,7 +193,7 @@ int mca_base_component_repository_link(const char *src_type, const char *depend_type, const char *depend_name) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT repository_item_t *src, *depend; /* Look up the two components */ @@ -232,7 +222,7 @@ int mca_base_component_repository_link(const char *src_type, */ void mca_base_component_repository_release(const mca_base_component_t *component) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT if (initialized) { repository_item_t *ri = find_component(component->mca_type_name, component->mca_component_name); @@ -249,12 +239,12 @@ void mca_base_component_repository_release(const mca_base_component_t *component */ void mca_base_component_repository_finalize(void) { -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT repository_item_t *ri, *next; #endif if (initialized) { -#if OPAL_WANT_LIBLTDL +#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 @@ -275,22 +265,17 @@ void mca_base_component_repository_finalize(void) } } while (opal_list_get_size(&repository) > 0); -#if OPAL_HAVE_LTDL_ADVISE - if (lt_dladvise_destroy(&opal_mca_dladvise)) { - return; - } -#endif - - /* Close down libltdl */ - - lt_dlexit(); + /* Close the dl framework (see comment about refcnt in + mca_base_component_repository_init()) */ + --opal_dl_base_framework.framework_refcnt; + (void) mca_base_framework_close(&opal_dl_base_framework); #endif initialized = false; } } -#if OPAL_WANT_LIBLTDL +#if OPAL_HAVE_DL_SUPPORT static repository_item_t *find_component(const char *type, const char *name) { @@ -379,7 +364,7 @@ static void ri_destructor(opal_object_t *obj) } /* Close the component (and potentially unload it from memory */ - lt_dlclose(ri->ri_dlhandle); + opal_dl_close(ri->ri_dlhandle); /* It should be obvious, but I'll state it anyway because it bit me during debugging: after the dlclose(), the mca_base_component_t @@ -419,4 +404,4 @@ static void di_destructor(opal_object_t *obj) OBJ_RELEASE(di->di_repository_entry); } -#endif /* OPAL_WANT_LIBLTDL */ +#endif /* OPAL_HAVE_DL_SUPPORT */ diff --git a/opal/mca/base/mca_base_component_repository.h b/opal/mca/base/mca_base_component_repository.h index 9d33bca0b7..fba0233420 100644 --- a/opal/mca/base/mca_base_component_repository.h +++ b/opal/mca/base/mca_base_component_repository.h @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -21,6 +22,9 @@ #include "opal_config.h" +#include "opal/mca/dl/dl.h" +#include "opal/mca/dl/base/base.h" + BEGIN_C_DECLS OPAL_DECLSPEC int mca_base_component_repository_init(void); @@ -33,37 +37,9 @@ BEGIN_C_DECLS * 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()). - * - * Note that internal to opal/mca/base, will *always* be - * included before this file, and is not included anywhere - * else in the OMPI tree. So checking for the LTDL_H preprocessor - * macro is a good indicator as to whether this file is being included - * from an opal/mca/base source file or not. If we are, then we need - * already have a real definition of lt_dlhandle. If we are being - * included from elsewhere, then will not previously have - * been included, LTDL_H will not be defined, and we need a fake - * definition of lt_dlhandle (or we'll get compile errors). So just - * typedef it to (void*). - * - * One more case that this handles is the --disable-dlopen case. In - * that case, even in opal/mca/base, we *won't* be including . - * Hence, LTDL_H won't be defined, so we'll end up typedefing - * lt_dlhandle to (void *). "But why does that matter?" you ask, "If - * we configure with --disable-dlopen, then lt_dlhandle shouldn't be - * used anywhere." Incorrect, Grasshopper. A small number of places - * (like the retain() function) are still prototyped, but have 99% of - * their innards #if'ed out -- i.e., they just return - * OPAL_ERR_NOT_SUPPORTED. Why was it coded up this way? I'm not - * entirely sure -- there may be a reason (and that reason may just be - * conservative coding), but I'm not really too inspired to look into - * it any further at this point. :-) */ -#if !defined(LTDL_H) - typedef void *lt_dlhandle; -#endif - OPAL_DECLSPEC int mca_base_component_repository_retain(char *type, - lt_dlhandle component_handle, + 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,