Index: opal/mca/base/Makefile.am =================================================================== --- opal/mca/base/Makefile.am (revision 28004) +++ opal/mca/base/Makefile.am (working copy) @@ -25,13 +25,15 @@ noinst_LTLIBRARIES = libmca_base.la -dist_pkgdata_DATA = help-mca-base.txt help-mca-param.txt +dist_pkgdata_DATA = help-mca-base.txt help-mca-var.txt # Source code files headers = \ base.h \ mca_base_component_repository.h \ + mca_base_var.h \ + mca_base_vari.h \ mca_base_param.h \ mca_base_param_internal.h @@ -50,6 +52,7 @@ mca_base_list.c \ mca_base_open.c \ mca_base_param.c \ + mca_base_var.c \ mca_base_parse_paramfile.c # Conditionally install the header files Index: opal/mca/base/help-mca-var.txt =================================================================== --- opal/mca/base/help-mca-var.txt (revision 0) +++ opal/mca/base/help-mca-var.txt (working copy) @@ -0,0 +1,91 @@ +# -*- text -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2013 Los Alamos National Security, LLC. All rights +# reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for Open MPI MCA error messages. +# +[invalid-flag-combination] +ERROR: An invalid combination of flags was passed to mca_base_var_register. + + Variable: %s + Flags: %s %s +# +[default-only-param-set] +WARNING: A user-supplied value attempted to override the default-only MCA +variable named "%s". + +The user-supplied value was ignored. +# +[missing-param-file] +Process %d Unable to locate the variable file "%s" in the following search path: + %s +# +[deprecated-mca-env] +A deprecated MCA variable value was specified in the environment or +on the command line. Deprecated MCA variables should be avoided; +they may disappear in future releases. + + Deprecated variable: %s +# +[deprecated-mca-cli] +A deprecated MCA variable value was specified on the command line. Deprecated +MCA variables should be avoided; they may disappear in future releases. + + Deprecated variable: %s +# +[deprecated-mca-file] +A deprecated MCA variable value was specified in an MCA variable +file. Deprecated MCA variables should be avoided; they may disappear +in future releases. + + Deprecated variable: %s + Source file: %s +# +[mutually-exclusive-vars] +Two mutually-exclusive MCA variables were specified. This can result +in undefined behavior, such as ignoring the components that the MCA +variables are supposed to affect. + + 1st MCA variable: %s + Source of value: %s + 2nd MCA variable: %s + Source of value: %s +# +[re-register-with-different-type] +An MCA variable was re-registered with a different type (i.e., it was +either originally registered as an INT and re-registered as a STRING, +or it was originially registered as a STRING and re-registered as an +INT). This a developer error; your job may abort. + + MCA variable name: %s +# +[overridden-param-set] +WARNING: A user-supplied value attempted to set a variable that is set +in the override variable file (openmpi-mca-params-override.conf). + + Variable: %s + +The user-supplied value was ignored. +# +[invalid-value] +An invalid value was supplied for an enum variable. + + Variable: %s + Value : %s Index: opal/mca/base/mca_base_param.c =================================================================== --- opal/mca/base/mca_base_param.c (revision 28004) +++ opal/mca/base/mca_base_param.c (working copy) @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana * University Research and Technology @@ -10,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2012 Los Alamos National Security, LLC. All rights + * Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights * reserved. * $COPYRIGHT$ * @@ -47,256 +48,149 @@ #include "opal/util/opal_environ.h" #include "opal/runtime/opal.h" -/* - * Local types - */ +#include "opal/mca/base/mca_base_var.h" -typedef struct { - /* Base class */ - opal_list_item_t super; - - /* String of the type name or NULL */ - char *si_type_name; - /* String of the component name */ - char *si_component_name; - /* String of the param name */ - char *si_param_name; - /* Full name of the synonym */ - char *si_full_name; - /* Name of the synonym's corresponding environment variable */ - char *si_env_var_name; - - /* Whether this synonym is a deprecated name or not */ - bool si_deprecated; - /* Whether we've shown a warning that this synonym has been - displayed or not */ - bool si_deprecated_warning_shown; -} syn_info_t; - - /* - * Public variables - * - * This variable is public, but not advertised in mca_base_param.h. - * It's only public so that the file parser can see it. - */ -opal_list_t mca_base_param_file_values; - -/* * local variables */ static opal_value_array_t mca_base_params; static const char *mca_prefix = "OMPI_MCA_"; -static char *home = NULL; -static char *cwd = NULL; static bool initialized = false; -static char * force_agg_path = NULL; /* * local functions */ -#if defined(__WINDOWS__) -static int read_keys_from_registry(HKEY hKey, char *sub_key, char *current_name); -#endif /* defined(__WINDOWS__) */ -static int fixup_files(char **file_list, char * path, bool rel_path_search); -static int read_files(char *file_list); -static int param_register(const char *type_name, - const char *component_name, - const char *param_name, - const char *help_msg, - mca_base_param_type_t type, - bool internal, - bool read_only, - mca_base_param_storage_t *default_value, - mca_base_param_storage_t *file_value, - mca_base_param_storage_t *override_value, - mca_base_param_storage_t *current_value); -static int syn_register(int index_orig, const char *syn_type_name, - const char *syn_component_name, - const char *syn_param_name, bool deprecated); -static bool param_lookup(size_t index, mca_base_param_storage_t *storage, - mca_base_param_source_t *source, - char **source_file); -static bool param_set_override(size_t index, - mca_base_param_storage_t *storage, - mca_base_param_type_t type); -static bool lookup_override(mca_base_param_t *param, - mca_base_param_storage_t *storage); -static bool lookup_env(mca_base_param_t *param, - mca_base_param_storage_t *storage); -static bool lookup_file(mca_base_param_t *param, - mca_base_param_storage_t *storage, - char **source_file); -static bool lookup_default(mca_base_param_t *param, - mca_base_param_storage_t *storage); -static bool set(mca_base_param_type_t type, - mca_base_param_storage_t *dest, mca_base_param_storage_t *src); static void param_constructor(mca_base_param_t *p); static void param_destructor(mca_base_param_t *p); -static void fv_constructor(mca_base_param_file_value_t *p); -static void fv_destructor(mca_base_param_file_value_t *p); static void info_constructor(mca_base_param_info_t *p); static void info_destructor(mca_base_param_info_t *p); -static void syn_info_constructor(syn_info_t *si); -static void syn_info_destructor(syn_info_t *si); -static mca_base_param_type_t param_type_from_index (size_t index); /* * Make the class instance for mca_base_param_t */ OBJ_CLASS_INSTANCE(mca_base_param_t, opal_object_t, param_constructor, param_destructor); -OBJ_CLASS_INSTANCE(mca_base_param_file_value_t, opal_list_item_t, - fv_constructor, fv_destructor); OBJ_CLASS_INSTANCE(mca_base_param_info_t, opal_list_item_t, info_constructor, info_destructor); -OBJ_CLASS_INSTANCE(syn_info_t, opal_list_item_t, - syn_info_constructor, syn_info_destructor); /* * Set it up */ int mca_base_param_init(void) { + int ret; + if (!initialized) { + initialized = true; - /* Init the value array for the param storage */ - OBJ_CONSTRUCT(&mca_base_params, opal_value_array_t); - opal_value_array_init(&mca_base_params, sizeof(mca_base_param_t)); + opal_value_array_init (&mca_base_params, sizeof (mca_base_param_t)); - /* Init the file param value list */ - - OBJ_CONSTRUCT(&mca_base_param_file_values, opal_list_t); - - /* Set this before we register the parameter, below */ - - initialized = true; - - mca_base_param_recache_files(false); + ret = mca_base_var_init (); + if (OPAL_SUCCESS != ret) { + return ret; + } } return OPAL_SUCCESS; } +/* Leave file caching up to the variable system */ int mca_base_param_recache_files(bool rel_path_search) { - int id; - char *files, *new_files = NULL, *new_agg_files = NULL; - char * new_agg_path = NULL, *agg_default_path = NULL; + return OPAL_SUCCESS; +} - /* We may need this later */ - home = (char*)opal_home_directory(); - - if(NULL == cwd) { - cwd = (char *) malloc(sizeof(char) * MAXPATHLEN); - if( NULL == (cwd = getcwd(cwd, MAXPATHLEN) )) { - opal_output(0, "Error: Unable to get the current working directory\n"); - cwd = strdup("."); - } +/* + * Register an MCA parameter + */ +static int register_param (const char *type_name, const char *component_name, + const char *param_name, const char *help_msg, + bool internal, bool read_only, mca_base_param_type_t type, + void *default_value, void *current_value) +{ + mca_base_var_flag_t flags = 0; + mca_base_var_type_t var_type; + mca_base_param_t param; + int ret, var_index; + + if (!initialized) { + mca_base_param_init (); } -#if OPAL_WANT_HOME_CONFIG_FILES - asprintf(&files, - "%s"OPAL_PATH_SEP".openmpi"OPAL_PATH_SEP"mca-params.conf%c%s"OPAL_PATH_SEP"openmpi-mca-params.conf", - home, OPAL_ENV_SEP, opal_install_dirs.sysconfdir); -#else - asprintf(&files, - "%s"OPAL_PATH_SEP"openmpi-mca-params.conf", - opal_install_dirs.sysconfdir); -#endif + OBJ_CONSTRUCT(¶m, mca_base_param_t); - /* Initialize a parameter that says where MCA param files can - be found */ + if (internal) { + flags |= MCA_BASE_VAR_FLAG_INTERNAL; + } + if (read_only) { + flags |= MCA_BASE_VAR_FLAG_DEFAULT_ONLY; + } - id = mca_base_param_reg_string_name("mca", "param_files", - "Path for MCA configuration files containing default parameter values", - false, false, files, &new_files); + /* Create a backing store for this parameter (needs to be malloc since the param + will be memcpy'd into the parameter list) */ + param.param_value = calloc (1, sizeof (*param.param_value)); + if (NULL == param.param_value) { + OBJ_DESTRUCT(¶m); + return OPAL_ERR_OUT_OF_RESOURCE; + } - /* Aggregate MCA parameter files - * A prefix search path to look up aggregate MCA parameter file - * requests that do not specify an absolute path - */ - id = mca_base_param_reg_string_name("mca", "base_param_file_prefix", - "Aggregate MCA parameter file sets", - false, false, NULL, &new_agg_files); - - asprintf(&agg_default_path, - "%s"OPAL_PATH_SEP"amca-param-sets%c%s", - opal_install_dirs.pkgdatadir, OPAL_ENV_SEP, cwd); - id = mca_base_param_reg_string_name("mca", "base_param_file_path", - "Aggregate MCA parameter Search path", - false, false, agg_default_path, &new_agg_path); + switch (type) { + case MCA_BASE_PARAM_TYPE_INT: + var_type = MCA_BASE_VAR_TYPE_INT; + param.param_value->intval = ((int *)default_value)[0]; + break; + case MCA_BASE_PARAM_TYPE_STRING: + if (default_value) { + param.param_value->stringval = strdup ((char *) default_value); + } + var_type = MCA_BASE_VAR_TYPE_STRING; + break; + case MCA_BASE_PARAM_TYPE_MAX: + OBJ_DESTRUCT(¶m); + return OPAL_ERROR; + } - id = mca_base_param_reg_string_name("mca", "base_param_file_path_force", - "Forced Aggregate MCA parameter Search path", - false, false, NULL, &force_agg_path); + /* There is no need to store a copy of the help message for unset. Passing + NULL when reregistering a variable will cause the variable system to + reuse the cached help message. */ - if( NULL != force_agg_path ) { - char *tmp_str = NULL; - if( NULL == new_agg_path ) { - new_agg_path = strdup(force_agg_path); - } - else { - tmp_str = strdup(new_agg_path); - free(new_agg_path); - asprintf(&new_agg_path, "%s%c%s", force_agg_path, OPAL_ENV_SEP, tmp_str); - free(tmp_str); - } + var_index = mca_base_var_register (NULL, type_name, component_name, + param_name, help_msg, var_type, NULL, + 0, flags, MCA_BASE_VAR_VERBOSITY_MPIDEV_ALL, + MCA_BASE_VAR_SCOPE_READONLY, + (void *) param.param_value); + + if (0 > var_index) { + return OPAL_ERROR; } - if( NULL != new_agg_files ) { - char *tmp_str = NULL; - - /* - * Resolve all relative paths. - * the file list returned will contain only absolute paths - */ - if( OPAL_SUCCESS != fixup_files(&new_agg_files, new_agg_path, rel_path_search) ) { -#if 0 - /* JJH We need to die! */ - abort(); -#else - ; -#endif + ret = opal_value_array_append_item (&mca_base_params, ¶m); + if (OPAL_SUCCESS != ret) { + return ret; + } + + if (current_value) { + switch (type) { + case MCA_BASE_PARAM_TYPE_INT: + ((int *) current_value)[0] = param.param_value->intval; + break; + case MCA_BASE_PARAM_TYPE_STRING: + + if (NULL != param.param_value->stringval) { + ((char **) current_value)[0] = strdup (param.param_value->stringval); + } else { + ((char **) current_value)[0] = NULL; + } + case MCA_BASE_PARAM_TYPE_MAX: + /* Impossible */ + break; } - else { - /* Prepend the files to the search list */ - asprintf(&tmp_str, "%s%c%s", new_agg_files, OPAL_ENV_SEP, new_files); - free(new_files); - new_files = strdup(tmp_str); - free(tmp_str); - } } - - read_files(new_files); -#if defined(__WINDOWS__) - read_keys_from_registry(HKEY_LOCAL_MACHINE, "SOFTWARE\\Open MPI", NULL); - read_keys_from_registry(HKEY_CURRENT_USER, "SOFTWARE\\Open MPI", NULL); -#endif /* defined(__WINDOWS__) */ - - free(files); - free(new_files); - if( NULL != new_agg_files ) { - free(new_agg_files); - new_agg_files = NULL; - } - if( NULL != agg_default_path ) { - free(agg_default_path); - agg_default_path = NULL; - } - if( NULL != new_agg_path ) { - free(new_agg_path); - new_agg_path = NULL; - } - return OPAL_SUCCESS; + return var_index; } - -/* - * Register an integer MCA parameter - */ int mca_base_param_reg_int(const mca_base_component_t *component, const char *param_name, const char *help_msg, @@ -305,23 +199,12 @@ int default_value, int *current_value) { - int ret; - mca_base_param_storage_t storage; - mca_base_param_storage_t lookup; - - storage.intval = default_value; - ret = param_register(component->mca_type_name, - component->mca_component_name, - param_name, help_msg, - MCA_BASE_PARAM_TYPE_INT, internal, read_only, - &storage, NULL, NULL, &lookup); - if (ret >= 0 && NULL != current_value) { - *current_value = lookup.intval; - } - return ret; + return register_param (component->mca_type_name, component->mca_component_name, + param_name, help_msg, internal, read_only, + MCA_BASE_PARAM_TYPE_INT, (void *) &default_value, + (void *) current_value); } - /* * Register an integer MCA parameter that is not associated with a * component @@ -334,24 +217,11 @@ int default_value, int *current_value) { - int ret; - mca_base_param_storage_t storage; - mca_base_param_storage_t lookup; - - storage.intval = default_value; - ret = param_register(type, NULL, param_name, help_msg, - MCA_BASE_PARAM_TYPE_INT, internal, read_only, - &storage, NULL, NULL, &lookup); - if (ret >= 0 && NULL != current_value) { - *current_value = lookup.intval; - } - return ret; + return register_param (type, NULL, param_name, help_msg, internal, read_only, + MCA_BASE_PARAM_TYPE_INT, (void *) &default_value, + (void *) current_value); } - -/* - * Register a string MCA parameter. - */ int mca_base_param_reg_string(const mca_base_component_t *component, const char *param_name, const char *help_msg, @@ -360,28 +230,12 @@ const char *default_value, char **current_value) { - int ret; - mca_base_param_storage_t storage; - mca_base_param_storage_t lookup; - - if (NULL != default_value) { - storage.stringval = (char *) default_value; - } else { - storage.stringval = NULL; - } - ret = param_register(component->mca_type_name, - component->mca_component_name, - param_name, help_msg, - MCA_BASE_PARAM_TYPE_STRING, internal, read_only, - &storage, NULL, NULL, - (NULL != current_value) ? &lookup : NULL); - if (ret >= 0 && NULL != current_value) { - *current_value = lookup.stringval; - } - return ret; + return register_param (component->mca_type_name, component->mca_component_name, + param_name, help_msg, internal, read_only, + MCA_BASE_PARAM_TYPE_STRING, (void *) default_value, + (void *) current_value); } - /* * Register a string MCA parameter that is not associated with a * component @@ -394,37 +248,29 @@ const char *default_value, char **current_value) { - int ret; - mca_base_param_storage_t storage; - mca_base_param_storage_t lookup; - - if (NULL != default_value) { - storage.stringval = (char *) default_value; - } else { - storage.stringval = NULL; - } - ret = param_register(type, NULL, param_name, help_msg, - MCA_BASE_PARAM_TYPE_STRING, internal, read_only, - &storage, NULL, NULL, - (NULL != current_value) ? &lookup : NULL); - if (ret >= 0 && NULL != current_value) { - *current_value = lookup.stringval; - } - return ret; + return register_param (type, NULL, param_name, help_msg, internal, read_only, + MCA_BASE_PARAM_TYPE_STRING, (void *) default_value, + (void *) current_value); } - /* * Register a synonym name for an existing MCA parameter */ +static int reg_syn (int index_orig, const char *type_name, const char *component_name, + const char *syn_param_name, bool deprecated) +{ + return mca_base_var_register_synonym (index_orig, NULL, type_name, + component_name, syn_param_name, + deprecated ? MCA_BASE_VAR_SYN_FLAG_DEPRECATED : 0); +} + int mca_base_param_reg_syn(int index_orig, const mca_base_component_t *syn_component, const char *syn_param_name, bool deprecated) { - return syn_register(index_orig, - syn_component->mca_type_name, - syn_component->mca_component_name, - syn_param_name, deprecated); + return reg_syn (index_orig, syn_component->mca_type_name, + syn_component->mca_component_name, syn_param_name, + deprecated); } /* @@ -434,8 +280,8 @@ const char *syn_type_name, const char *syn_param_name, bool deprecated) { - return syn_register(index_orig, syn_type_name, NULL, - syn_param_name, deprecated); + return reg_syn (index_orig, syn_type_name, NULL, syn_param_name, + deprecated); } /* @@ -443,13 +289,27 @@ */ int mca_base_param_lookup_int(int index, int *value) { - mca_base_param_storage_t storage; - - if (param_lookup(index, &storage, NULL, NULL)) { - *value = storage.intval; + mca_base_var_t *var; + const mca_base_var_storage_t *tmp; + int ret; + + ret = mca_base_var_get (index, &var); + if (OPAL_SUCCESS != ret) { + return ret; + } + + ret = mca_base_var_get_value (index, &tmp, NULL, NULL); + if (OPAL_SUCCESS != ret) { + return ret; + } + + if (MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) { + *value = tmp->boolval; + } else { + *value = tmp->intval; + } + return OPAL_SUCCESS; - } - return OPAL_ERROR; } @@ -458,12 +318,8 @@ */ int mca_base_param_set_int(int index, int value) { - mca_base_param_storage_t storage; - - mca_base_param_unset(index); - storage.intval = value; - param_set_override(index, &storage, MCA_BASE_PARAM_TYPE_INT); - return OPAL_SUCCESS; + return mca_base_var_set_value (index, &value, sizeof (value), + MCA_BASE_VAR_SOURCE_SET, NULL); } /* @@ -471,23 +327,7 @@ */ int mca_base_param_deregister(int index) { - mca_base_param_t *array; - size_t size; - - /* Lookup the index and see if the index and parameter are valid */ - size = opal_value_array_get_size(&mca_base_params); - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - if (index < 0 || ((size_t) index) > size || - MCA_BASE_PARAM_TYPE_MAX >= array[index].mbp_type) { - return OPAL_ERROR; - } - - /* Do not remove this item from the array otherwise we will change - all the indices of parameters with a larger index. The destructor - will mark this parameter as invalid. */ - OBJ_DESTRUCT(&array[index]); - - return OPAL_SUCCESS; + return mca_base_var_deregister (index); } /* @@ -495,13 +335,25 @@ */ int mca_base_param_lookup_string(int index, char **value) { - mca_base_param_storage_t storage; - - if (param_lookup(index, &storage, NULL, NULL)) { - *value = storage.stringval; + const char **tmp; + int ret; + + *value = NULL; + + ret = mca_base_var_get_value (index, &tmp, NULL, NULL); + if (OPAL_SUCCESS != ret) { + return ret; + } + + /* MCA param users expect us to return a copy of the string */ + if (tmp && tmp[0]) { + *value = strdup (tmp[0]); + if (NULL == *value) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + return OPAL_SUCCESS; - } - return OPAL_ERROR; } @@ -510,32 +362,46 @@ */ int mca_base_param_set_string(int index, char *value) { - mca_base_param_storage_t storage; - - mca_base_param_unset(index); - storage.stringval = value; - param_set_override(index, &storage, MCA_BASE_PARAM_TYPE_STRING); - return OPAL_SUCCESS; + return mca_base_var_set_value (index, value, value ? strlen (value) : 0, + MCA_BASE_VAR_SOURCE_SET, NULL); } /* * Lookup the source of an MCA param's value */ -int mca_base_param_lookup_source(int index, mca_base_param_source_t *source, char **source_file) +int mca_base_param_lookup_source(int index, mca_base_param_source_t *source, const char **source_file) { - mca_base_param_storage_t storage; - int rc; + mca_base_var_source_t var_source; + int ret; - storage.stringval = NULL; + ret = mca_base_var_get_value (index, NULL, &var_source, source_file); + if (OPAL_SUCCESS != ret) { + return ret; + } - rc = param_lookup(index, &storage, source, source_file); - if (MCA_BASE_PARAM_TYPE_STRING == param_type_from_index (index) && - NULL != storage.stringval) { - free (storage.stringval); + if (NULL != source) { + switch (var_source) { + case MCA_BASE_VAR_SOURCE_ENV: + case MCA_BASE_VAR_SOURCE_COMMAND_LINE: + *source = MCA_BASE_PARAM_SOURCE_ENV; + break; + case MCA_BASE_VAR_SOURCE_FILE: + case MCA_BASE_VAR_SOURCE_OVERRIDE: + *source = MCA_BASE_PARAM_SOURCE_FILE; + break; + case MCA_BASE_VAR_SOURCE_SET: + *source = MCA_BASE_PARAM_SOURCE_OVERRIDE; + break; + case MCA_BASE_VAR_SOURCE_DEFAULT: + *source = MCA_BASE_PARAM_SOURCE_DEFAULT; + break; + case MCA_BASE_VAR_SOURCE_MAX: + return OPAL_ERROR; + } } - return rc ? OPAL_SUCCESS : OPAL_ERROR; + return OPAL_SUCCESS; } /* @@ -543,43 +409,32 @@ */ int mca_base_param_unset(int index) { - size_t len; - mca_base_param_t *array; - - if (!initialized) { - return OPAL_ERROR; - } - - len = opal_value_array_get_size(&mca_base_params); - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - if (index < 0 || ((size_t) index) > len || - MCA_BASE_PARAM_TYPE_MAX <= array[index].mbp_type) { - return OPAL_ERROR; - } - - /* We have a valid entry so save the internal flag */ - if (array[index].mbp_override_value_set) { - if (MCA_BASE_PARAM_TYPE_STRING == array[index].mbp_type && - NULL != array[index].mbp_override_value.stringval) { - free(array[index].mbp_override_value.stringval); - array[index].mbp_override_value.stringval = NULL; - } - } - array[index].mbp_override_value_set = false; - - /* All done */ - - return OPAL_SUCCESS; + /* It is possible to support the semantics of unset by: + * 1) When registering the parameter, save the default. + * 2) On calling unset, lookup the default (can only be done for + * parameters that use the old system). + * 3) Deregister the parameter + * 4) Set the default + * 5) Register the parameter. + * + * The mca_base_var system will ensure the parameter keeps the + * same index and will do the lookup (env, file, default) again. + */ + return OPAL_ERR_NOT_SUPPORTED; } char *mca_base_param_env_var(const char *param_name) { - char *name; + char *var_name; + int ret; - asprintf(&name, "%s%s", mca_prefix, param_name); + ret = mca_base_var_env_name (param_name, &var_name); + if (OPAL_SUCCESS != ret) { + return NULL; + } - return name; + return var_name; } @@ -589,148 +444,122 @@ int mca_base_param_find(const char *type_name, const char *component_name, const char *param_name) { - size_t i, size; - mca_base_param_t *array; - - /* Check for bozo cases */ - - if (!initialized) { - return OPAL_ERROR; - } - - /* Loop through looking for a parameter of a given - type/component/param */ - - size = opal_value_array_get_size(&mca_base_params); - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - for (i = 0; i < size; ++i) { - if (((NULL == type_name && NULL == array[i].mbp_type_name) || - (NULL != type_name && NULL != array[i].mbp_type_name && - (0 == strcmp(type_name, array[i].mbp_type_name)))) && - ((NULL == component_name && NULL == array[i].mbp_component_name) || - (NULL != component_name && NULL != array[i].mbp_component_name && - 0 == strcmp(component_name, array[i].mbp_component_name))) && - ((NULL == param_name && NULL == array[i].mbp_param_name) || - (NULL != param_name && NULL != array[i].mbp_param_name && - 0 == strcmp(param_name, array[i].mbp_param_name)))) { - return (int)i; - } - } - - /* Didn't find it */ - - return OPAL_ERROR; + return mca_base_var_find (NULL, type_name, component_name, param_name); } - -int mca_base_param_set_internal(int index, bool internal) +int mca_base_param_set_internal (int index, bool internal) { - size_t len; - mca_base_param_t *array; - - /* Check for bozo cases */ - - if (!initialized) { - return OPAL_ERROR; - } - - len = opal_value_array_get_size(&mca_base_params); - if (((size_t) index) > len) { - return OPAL_ERROR; - } - - /* We have a valid entry (remember that we never delete MCA - parameters, so if the index is >0 and array[i].mbp_type) { + const mca_base_var_t *var, *syn; + + ret = mca_base_var_get (i, &var); + if (OPAL_SUCCESS != ret) { + continue; + } + + /* Dump this variable only if it is not a synonym and either it + is not internal or internal variables were requested */ + if ((internal || !(var->mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL)) && + 0 > var->mbv_synonym_for) { + const mca_base_var_group_t *group; + + ret = mca_base_var_group_get (var->mbv_group_index, &group); + if (OPAL_SUCCESS != ret) { + continue; + } + p = OBJ_NEW(mca_base_param_info_t); if (NULL == p) { return OPAL_ERR_OUT_OF_RESOURCE; } - p->mbpp_index = (int)i; - p->mbpp_type_name = array[i].mbp_type_name; - p->mbpp_component_name = array[i].mbp_component_name; - p->mbpp_param_name = array[i].mbp_param_name; - p->mbpp_full_name = array[i].mbp_full_name; - p->mbpp_deprecated = array[i].mbp_deprecated; - p->mbpp_internal = array[i].mbp_internal; - p->mbpp_read_only = array[i].mbp_read_only; - p->mbpp_type = array[i].mbp_type; - p->mbpp_help_msg = array[i].mbp_help_msg; + p->mbpp_index = i; + p->mbpp_type_name = group->group_framework; + p->mbpp_component_name = group->group_component; + p->mbpp_param_name = var->mbv_variable_name; + p->mbpp_full_name = var->mbv_full_name; + p->mbpp_deprecated = !!(var->mbv_flags & MCA_BASE_VAR_FLAG_DEPRECATED); + p->mbpp_internal = !!(var->mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL); + p->mbpp_read_only = !!(var->mbv_flags & MCA_BASE_VAR_FLAG_DEFAULT_ONLY); + if (var->mbv_type == MCA_BASE_VAR_TYPE_INT || + var->mbv_type == MCA_BASE_VAR_TYPE_BOOL) { + p->mbpp_type = MCA_BASE_PARAM_TYPE_INT; + } else { + p->mbpp_type = MCA_BASE_PARAM_TYPE_STRING; + } + p->mbpp_help_msg = var->mbv_description; + /* Save this entry to the list */ - opal_list_append(*info, (opal_list_item_t*) p); + opal_list_append(*info, &p->super); - /* If this param has synonyms, add them too */ - if (NULL != array[i].mbp_synonyms && - !opal_list_is_empty(array[i].mbp_synonyms)) { - p->mbpp_synonyms_len = - (int) opal_list_get_size(array[i].mbp_synonyms); - p->mbpp_synonyms = malloc(sizeof(mca_base_param_info_t*) * - p->mbpp_synonyms_len); + p->mbpp_synonyms_len = opal_value_array_get_size ((opal_value_array_t *) &var->mbv_synonyms); + + if (p->mbpp_synonyms_len) { + p->mbpp_synonyms = calloc(p->mbpp_synonyms_len, + sizeof (mca_base_param_info_t *)); if (NULL == p->mbpp_synonyms) { - p->mbpp_synonyms_len = 0; return OPAL_ERR_OUT_OF_RESOURCE; } - - for (j = 0, item = opal_list_get_first(array[i].mbp_synonyms); - opal_list_get_end(array[i].mbp_synonyms) != item; - ++j, item = opal_list_get_next(item)) { - si = (syn_info_t*) item; + + synonyms = OPAL_VALUE_ARRAY_GET_BASE(&var->mbv_synonyms, int); + + for (j = 0 ; j < (size_t) p->mbpp_synonyms_len ; ++j) { + ret = mca_base_var_get (synonyms[j], &syn); + if (OPAL_SUCCESS != ret) { + p->mbpp_synonyms[j] = NULL; + continue; + } + + ret = mca_base_var_group_get (syn->mbv_group_index, &group); + if (OPAL_SUCCESS != ret) { + continue; + } + q = OBJ_NEW(mca_base_param_info_t); if (NULL == q) { + p->mbpp_synonyms_len = j; return OPAL_ERR_OUT_OF_RESOURCE; } - q->mbpp_index = (int)i; - q->mbpp_type_name = si->si_type_name; - q->mbpp_component_name = si->si_component_name; - q->mbpp_param_name = si->si_param_name; - q->mbpp_full_name = si->si_full_name; - q->mbpp_deprecated = si->si_deprecated || - array[i].mbp_deprecated; - q->mbpp_internal = array[i].mbp_internal; - q->mbpp_read_only = array[i].mbp_read_only; - q->mbpp_type = array[i].mbp_type; - q->mbpp_help_msg = array[i].mbp_help_msg; + q->mbpp_index = (int) i; + q->mbpp_type_name = group->group_framework; + q->mbpp_component_name = group->group_component; + q->mbpp_param_name = syn->mbv_variable_name; + q->mbpp_full_name = syn->mbv_full_name; + q->mbpp_deprecated = !!(syn->mbv_flags & MCA_BASE_VAR_FLAG_DEPRECATED); + q->mbpp_internal = !!(syn->mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL); + q->mbpp_read_only = !!(syn->mbv_flags & MCA_BASE_VAR_FLAG_DEFAULT_ONLY); + q->mbpp_type = syn->mbv_type; + q->mbpp_help_msg = syn->mbv_description; + /* Let this one point to the original */ q->mbpp_synonym_parent = p; @@ -738,7 +567,7 @@ p->mbpp_synonyms[j] = q; /* Save this entry to the list */ - opal_list_append(*info, (opal_list_item_t*) q); + opal_list_append(*info, &q->super); } } } @@ -755,64 +584,7 @@ */ int mca_base_param_build_env(char ***env, int *num_env, bool internal) { - size_t i, len; - mca_base_param_t *array; - char *str; - mca_base_param_storage_t storage; - - /* Check for bozo cases */ - - if (!initialized) { - return OPAL_ERROR; - } - - /* Iterate through all the registered parameters */ - - len = opal_value_array_get_size(&mca_base_params); - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - for (i = 0; i < len; ++i) { - /* Don't output read-only values */ - if (array[i].mbp_read_only) { - continue; - } - - if (array[i].mbp_internal == internal || internal) { - if (param_lookup(i, &storage, NULL, NULL)) { - if (MCA_BASE_PARAM_TYPE_INT == array[i].mbp_type) { - asprintf(&str, "%s=%d", array[i].mbp_env_var_name, - storage.intval); - opal_argv_append(num_env, env, str); - free(str); - } else if (MCA_BASE_PARAM_TYPE_STRING == array[i].mbp_type) { - if (NULL != storage.stringval) { - asprintf(&str, "%s=%s", array[i].mbp_env_var_name, - storage.stringval); - free(storage.stringval); - opal_argv_append(num_env, env, str); - free(str); - } - } else { - goto cleanup; - } - } else { - goto cleanup; - } - } - } - - /* All done */ - - return OPAL_SUCCESS; - - /* Error condition */ - - cleanup: - if (*num_env > 0) { - opal_argv_free(*env); - *num_env = 0; - *env = NULL; - } - return OPAL_ERR_NOT_FOUND; + return mca_base_var_build_env (env, num_env, internal); } @@ -824,10 +596,10 @@ { opal_list_item_t *item; - for (item = opal_list_remove_first(info); NULL != item; - item = opal_list_remove_first(info)) { + while (NULL != (item = opal_list_remove_first(info))) { OBJ_RELEASE(item); } + OBJ_RELEASE(info); return OPAL_SUCCESS; @@ -840,37 +612,23 @@ */ int mca_base_param_finalize(void) { - opal_list_item_t *item; mca_base_param_t *array; + size_t size, i; + int ret; if (initialized) { - int size, i; + ret = mca_base_var_finalize (); + if (OPAL_SUCCESS != ret) { + return ret; + } size = opal_value_array_get_size(&mca_base_params); array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); for (i = 0 ; i < size ; ++i) { - if (MCA_BASE_PARAM_TYPE_MAX > array[i].mbp_type) { - OBJ_DESTRUCT(&array[i]); - } + OBJ_DESTRUCT(&array[i]); } OBJ_DESTRUCT(&mca_base_params); - while (NULL != - (item = opal_list_remove_first(&mca_base_param_file_values))) { - OBJ_RELEASE(item); - } - OBJ_DESTRUCT(&mca_base_param_file_values); - - if( NULL != cwd ) { - free(cwd); - cwd = NULL; - } - - if( NULL != force_agg_path ) { - free(force_agg_path); - force_agg_path = NULL; - } - initialized = false; } @@ -879,1086 +637,12 @@ return OPAL_SUCCESS; } - -/*************************************************************************/ -static int fixup_files(char **file_list, char * path, bool rel_path_search) { - int exit_status = OPAL_SUCCESS; - char **files = NULL; - char **search_path = NULL; - char * tmp_file = NULL; - char **argv = NULL; - int mode = R_OK; /* The file exists, and we can read it */ - int count, i, argc = 0; - - search_path = opal_argv_split(path, OPAL_ENV_SEP); - files = opal_argv_split(*file_list, OPAL_ENV_SEP); - count = opal_argv_count(files); - - /* Read in reverse order, so we can preserve the original ordering */ - for (i = 0 ; i < count; ++i) { - /* Absolute paths preserved */ - if ( opal_path_is_absolute(files[i]) ) { - if( NULL == opal_path_access(files[i], NULL, mode) ) { - opal_show_help("help-mca-param.txt", "missing-param-file", - true, getpid(), files[i], path); - exit_status = OPAL_ERROR; - goto cleanup; - } - else { - opal_argv_append(&argc, &argv, files[i]); - } - } - /* Resolve all relative paths: - * - If filename contains a "/" (e.g., "./foo" or "foo/bar") - * - look for it relative to cwd - * - if exists, use it - * - ow warn/error - */ - else if (!rel_path_search && NULL != strchr(files[i], OPAL_PATH_SEP[0]) ) { - if( NULL != force_agg_path ) { - tmp_file = opal_path_access(files[i], force_agg_path, mode); - } - else { - tmp_file = opal_path_access(files[i], cwd, mode); - } - - if( NULL == tmp_file ) { - opal_show_help("help-mca-param.txt", "missing-param-file", - true, getpid(), files[i], cwd); - exit_status = OPAL_ERROR; - goto cleanup; - } - else { - opal_argv_append(&argc, &argv, tmp_file); - } - } - /* Resolve all relative paths: - * - Use path resolution - * - if found and readable, use it - * - otherwise, warn/error - */ - else { - if( NULL != (tmp_file = opal_path_find(files[i], search_path, mode, NULL)) ) { - opal_argv_append(&argc, &argv, tmp_file); - free(tmp_file); - tmp_file = NULL; - } - else { - opal_show_help("help-mca-param.txt", "missing-param-file", - true, getpid(), files[i], path); - exit_status = OPAL_ERROR; - goto cleanup; - } - } - } - - free(*file_list); - *file_list = opal_argv_join(argv, OPAL_ENV_SEP); - - cleanup: - if( NULL != files ) { - opal_argv_free(files); - files = NULL; - } - if( NULL != argv ) { - opal_argv_free(argv); - argv = NULL; - } - if( NULL != search_path ) { - opal_argv_free(search_path); - search_path = NULL; - } - if( NULL != tmp_file ) { - free(tmp_file); - tmp_file = NULL; - } - - return exit_status; -} - -static int read_files(char *file_list) -{ - int i, count; - char **files; - - /* Iterate through all the files passed in -- read them in reverse - order so that we preserve unix/shell path-like semantics (i.e., - the entries farthest to the left get precedence) */ - - files = opal_argv_split(file_list, OPAL_ENV_SEP); - count = opal_argv_count(files); - - for (i = count - 1; i >= 0; --i) { - mca_base_parse_paramfile(files[i]); - } - opal_argv_free(files); - - return OPAL_SUCCESS; -} - -/** - * - */ -#if defined(__WINDOWS__) -#define MAX_KEY_LENGTH 255 -#define MAX_VALUE_NAME 16383 - -static int read_keys_from_registry(HKEY hKey, char *sub_key, char *current_name) -{ - TCHAR achKey[MAX_KEY_LENGTH]; /* buffer for subkey name */ - DWORD cbName; /* size of name string */ - TCHAR achClass[MAX_PATH] = TEXT(""); /* buffer for class name */ - DWORD cchClassName = MAX_PATH; /* size of class string */ - DWORD cSubKeys=0; /* number of subkeys */ - DWORD cbMaxSubKey; /* longest subkey size */ - DWORD cchMaxClass; /* longest class string */ - DWORD cValues; /* number of values for key */ - DWORD cchMaxValue; /* longest value name */ - DWORD cbMaxValueData; /* longest value data */ - DWORD cbSecurityDescriptor; /* size of security descriptor */ - - LPDWORD lpType; - LPDWORD word_lpData; - TCHAR str_lpData[MAX_VALUE_NAME]; - TCHAR *str_key_name, *type_name, *next_name; - DWORD dwSize, i, retCode, type_len, param_type; - TCHAR achValue[MAX_VALUE_NAME]; - DWORD cchValue = MAX_VALUE_NAME; - HKEY hTestKey; - char *sub_sub_key; - mca_base_param_storage_t storage, override, lookup; - - if( !RegOpenKeyEx( hKey, sub_key, 0, KEY_READ, &hTestKey) == ERROR_SUCCESS ) - return OPAL_ERROR; - - /* Get the class name and the value count. */ - retCode = RegQueryInfoKey( hTestKey, /* key handle */ - achClass, /* buffer for class name */ - &cchClassName, /* size of class string */ - NULL, /* reserved */ - &cSubKeys, /* number of subkeys */ - &cbMaxSubKey, /* longest subkey size */ - &cchMaxClass, /* longest class string */ - &cValues, /* number of values for this key */ - &cchMaxValue, /* longest value name */ - &cbMaxValueData, /* longest value data */ - &cbSecurityDescriptor, /* security descriptor */ - NULL ); - - /* Enumerate the subkeys, until RegEnumKeyEx fails. */ - for (i = 0; i < cSubKeys; i++) { - cbName = MAX_KEY_LENGTH; - retCode = RegEnumKeyEx(hTestKey, i, achKey, &cbName, NULL, NULL, NULL, NULL); - if (retCode != ERROR_SUCCESS) continue; - asprintf(&sub_sub_key, "%s\\%s", sub_key, achKey); - if( NULL != current_name ) { - asprintf(&next_name, "%s_%s", current_name, achKey); - } else { - asprintf(&next_name, "%s", achKey); - } - read_keys_from_registry(hKey, sub_sub_key, next_name); - free(next_name); - free(sub_sub_key); - } - - /* Enumerate the key values. */ - for( i = 0; i < cValues; i++ ) { - cchValue = MAX_VALUE_NAME; - achValue[0] = '\0'; - retCode = RegEnumValue(hTestKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL); - if (retCode != ERROR_SUCCESS ) continue; - - /* lpType - get the type of the value - * dwSize - get the size of the buffer to hold the value - */ - retCode = RegQueryValueEx(hTestKey, achValue, NULL, (LPDWORD)&lpType, NULL, &dwSize); - - if (strcmp(achValue,"")) { - if (current_name!=NULL) - asprintf(&type_name, "%s_%s", current_name, achValue); - else - asprintf(&type_name, "%s", achValue); - } else { - if (current_name!=NULL) - asprintf(&type_name, "%s", current_name); - else - asprintf(&type_name, "%s", achValue); - } - - type_len = strcspn(type_name, "_"); - str_key_name = type_name + type_len + 1; - if( type_len == strlen(type_name) ) - str_key_name = NULL; - type_name[type_len] = '\0'; - - retCode = 1; - if( lpType == (LPDWORD)REG_SZ ) { /* REG_SZ = 1 */ - retCode = RegQueryValueEx(hTestKey, achValue, NULL, NULL, (LPBYTE)&str_lpData, &dwSize); - storage.stringval = (char*)str_lpData; - override.stringval = (char*)str_lpData; - param_type = MCA_BASE_PARAM_TYPE_STRING; - } else if( lpType == (LPDWORD)REG_DWORD ) { /* REG_DWORD = 4 */ - retCode = RegQueryValueEx(hTestKey, achValue, NULL, NULL, (LPBYTE)&word_lpData, &dwSize); - storage.intval = (int)word_lpData; - override.intval = (int)word_lpData; - param_type = MCA_BASE_PARAM_TYPE_INT; - } - if( !retCode ) { - (void)param_register( type_name, NULL, str_key_name, NULL, - param_type, false, false, - &storage, NULL, &override, &lookup ); - } else { - opal_output( 0, "error reading value of param_name: %s with %d error.\n", - str_key_name, retCode); - } - - free(type_name); - } - - RegCloseKey( hKey ); - - return OPAL_SUCCESS; -} -#endif /* defined(__WINDOWS__) */ - -/******************************************************************************/ - - -static int param_register(const char *type_name, - const char *component_name, - const char *param_name, - const char *help_msg, - mca_base_param_type_t type, - bool internal, - bool read_only, - mca_base_param_storage_t *default_value, - mca_base_param_storage_t *file_value, - mca_base_param_storage_t *override_value, - mca_base_param_storage_t *current_value) -{ - int ret; - size_t i, len; - mca_base_param_t param, *array; - - /* There are data holes in the param struct */ - OPAL_DEBUG_ZERO(param); - - /* Initialize the array if it has never been initialized */ - - if (!initialized) { - mca_base_param_init(); - } - - /* Create a parameter entry */ - - OBJ_CONSTRUCT(¶m, mca_base_param_t); - param.mbp_type = type; - param.mbp_internal = internal; - param.mbp_read_only = read_only; - if (NULL != help_msg) { - param.mbp_help_msg = strdup(help_msg); - } - - if (NULL != type_name) { - param.mbp_type_name = strdup(type_name); - if (NULL == param.mbp_type_name) { - OBJ_DESTRUCT(¶m); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - if (NULL != component_name) { - param.mbp_component_name = strdup(component_name); - if (NULL == param.mbp_component_name) { - OBJ_DESTRUCT(¶m); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - param.mbp_param_name = NULL; - if (NULL != param_name) { - param.mbp_param_name = strdup(param_name); - if (NULL == param.mbp_param_name) { - OBJ_DESTRUCT(¶m); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - - /* Build up the full name */ - len = 16; - if (NULL != type_name) { - len += strlen(type_name); - } - if (NULL != param.mbp_component_name) { - len += strlen(param.mbp_component_name); - } - if (NULL != param.mbp_param_name) { - len += strlen(param.mbp_param_name); - } - - param.mbp_full_name = (char*)malloc(len); - if (NULL == param.mbp_full_name) { - OBJ_DESTRUCT(¶m); - return OPAL_ERROR; - } - - /* Copy the name over in parts */ - - param.mbp_full_name[0] = '\0'; - if (NULL != type_name) { - strncat(param.mbp_full_name, type_name, len); - } - if (NULL != component_name) { - if ('\0' != param.mbp_full_name[0]) { - strcat(param.mbp_full_name, "_"); - } - strcat(param.mbp_full_name, component_name); - } - if (NULL != param_name) { - if ('\0' != param.mbp_full_name[0]) { - strcat(param.mbp_full_name, "_"); - } - strcat(param.mbp_full_name, param_name); - } - - /* Create the environment name */ - - len = strlen(param.mbp_full_name) + strlen(mca_prefix) + 16; - param.mbp_env_var_name = (char*)malloc(len); - if (NULL == param.mbp_env_var_name) { - OBJ_DESTRUCT(¶m); - return OPAL_ERROR; - } - snprintf(param.mbp_env_var_name, len, "%s%s", mca_prefix, - param.mbp_full_name); - - /* Figure out the default value; zero it out if a default is not - provided */ - - if (NULL != default_value) { - if (MCA_BASE_PARAM_TYPE_STRING == param.mbp_type && - NULL != default_value->stringval) { - param.mbp_default_value.stringval = strdup(default_value->stringval); - } else { - param.mbp_default_value = *default_value; - } - } else { - memset(¶m.mbp_default_value, 0, sizeof(param.mbp_default_value)); - } - - /* Figure out the file value; zero it out if a file is not - provided */ - - if (NULL != file_value) { - if (MCA_BASE_PARAM_TYPE_STRING == param.mbp_type && - NULL != file_value->stringval) { - param.mbp_file_value.stringval = strdup(file_value->stringval); - } else { - param.mbp_file_value = *file_value; - } - param.mbp_file_value_set = true; - } else { - memset(¶m.mbp_file_value, 0, sizeof(param.mbp_file_value)); - param.mbp_file_value_set = false; - } - - /* Figure out the override value; zero it out if a override is not - provided */ - - if (NULL != override_value) { - if (MCA_BASE_PARAM_TYPE_STRING == param.mbp_type && - NULL != override_value->stringval) { - param.mbp_override_value.stringval = strdup(override_value->stringval); - } else { - param.mbp_override_value = *override_value; - } - param.mbp_override_value_set = true; - } else { - memset(¶m.mbp_override_value, 0, sizeof(param.mbp_override_value)); - param.mbp_override_value_set = false; - } - - /* See if this entry is already in the array */ - - len = opal_value_array_get_size(&mca_base_params); - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - for (i = 0; i < len; ++i) { - if (0 == strcmp(param.mbp_full_name, array[i].mbp_full_name)) { - - /* We found an entry with the same param name. Check to - ensure that we're not changing types */ - /* Easy case: both are INT */ - - if (MCA_BASE_PARAM_TYPE_INT == array[i].mbp_type && - MCA_BASE_PARAM_TYPE_INT == param.mbp_type) { - if (NULL != default_value) { - array[i].mbp_default_value.intval = - param.mbp_default_value.intval; - } - if (NULL != file_value) { - array[i].mbp_file_value.intval = - param.mbp_file_value.intval; - array[i].mbp_file_value_set = true; - } - if (NULL != override_value) { - array[i].mbp_override_value.intval = - param.mbp_override_value.intval; - array[i].mbp_override_value_set = true; - } - } - - /* Both are STRING */ - - else if (MCA_BASE_PARAM_TYPE_STRING == array[i].mbp_type && - MCA_BASE_PARAM_TYPE_STRING == param.mbp_type) { - if (NULL != default_value) { - if (NULL != array[i].mbp_default_value.stringval) { - free(array[i].mbp_default_value.stringval); - array[i].mbp_default_value.stringval = NULL; - } - if (NULL != param.mbp_default_value.stringval) { - array[i].mbp_default_value.stringval = - strdup(param.mbp_default_value.stringval); - } - } - - if (NULL != file_value) { - if (NULL != array[i].mbp_file_value.stringval) { - free(array[i].mbp_file_value.stringval); - array[i].mbp_file_value.stringval = NULL; - } - if (NULL != param.mbp_file_value.stringval) { - array[i].mbp_file_value.stringval = - strdup(param.mbp_file_value.stringval); - } - array[i].mbp_file_value_set = true; - } - - if (NULL != override_value) { - if (NULL != array[i].mbp_override_value.stringval) { - free(array[i].mbp_override_value.stringval); - array[i].mbp_override_value.stringval = NULL; - } - if (NULL != param.mbp_override_value.stringval) { - array[i].mbp_override_value.stringval = - strdup(param.mbp_override_value.stringval); - } - array[i].mbp_override_value_set = true; - } - } - - /* If the original is INT and the new is STRING, or the original - is STRING and the new is INT, this is an OMPI developer - error. */ - - else if ((MCA_BASE_PARAM_TYPE_INT == array[i].mbp_type && - MCA_BASE_PARAM_TYPE_STRING == param.mbp_type) || - (MCA_BASE_PARAM_TYPE_STRING == array[i].mbp_type && - MCA_BASE_PARAM_TYPE_INT == param.mbp_type)) { -#if OPAL_ENABLE_DEBUG - opal_show_help("help-mca-param.txt", - "re-register with different type", - true, array[i].mbp_full_name); -#endif - /* Return an error code and hope for the best. */ - OBJ_DESTRUCT(¶m); - return OPAL_ERR_VALUE_OUT_OF_BOUNDS; - } - - /* Now delete the newly-created entry (since we just saved the - value in the old entry) */ - - OBJ_DESTRUCT(¶m); - - /* Finally, if we have a lookup value, look it up */ - - if (NULL != current_value) { - if (!param_lookup(i, current_value, NULL, NULL)) { - return OPAL_ERR_NOT_FOUND; - } - } - - /* Return the new index */ - - return (int)i; - } - } - - /* Add it to the array. Note that we copy the mca_param_t by value, - so the entire contents of the struct is copied. The synonym list - will always be empty at this point, so there's no need for an - extra RETAIN or RELEASE. */ - if (OPAL_SUCCESS != - (ret = opal_value_array_append_item(&mca_base_params, ¶m))) { - return ret; - } - ret = (int)opal_value_array_get_size(&mca_base_params) - 1; - - /* Finally, if we have a lookup value, look it up */ - - if (NULL != current_value) { - if (!param_lookup(ret, current_value, NULL, NULL)) { - return OPAL_ERR_NOT_FOUND; - } - } - - /* All done */ - - return ret; -} - - /* - * Back-end for registering a synonym - */ -static int syn_register(int index_orig, const char *syn_type_name, - const char *syn_component_name, - const char *syn_param_name, bool deprecated) -{ - size_t len; - syn_info_t *si; - mca_base_param_t *array; - - if (!initialized) { - return OPAL_ERROR; - } - - /* Sanity check index param */ - len = opal_value_array_get_size(&mca_base_params); - if (index_orig < 0 || ((size_t) index_orig) > len) { - return OPAL_ERR_BAD_PARAM; - } - - /* Make the synonym info object */ - si = OBJ_NEW(syn_info_t); - if (NULL == si) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - - /* Note that the following logic likely could have been combined - into more compact code. However, keeping it separate made it - much easier to read / maintain (IMHO). This is not a high - performance section of the code, so a premium was placed on - future readability / maintenance. */ - - /* Save the function parameters */ - si->si_deprecated = deprecated; - if (NULL != syn_type_name) { - si->si_type_name = strdup(syn_type_name); - if (NULL == si->si_type_name) { - OBJ_RELEASE(si); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - - if (NULL != syn_component_name) { - si->si_component_name = strdup(syn_component_name); - if (NULL == si->si_component_name) { - OBJ_RELEASE(si); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - - if (NULL != syn_param_name) { - si->si_param_name = strdup(syn_param_name); - if (NULL == si->si_param_name) { - OBJ_RELEASE(si); - return OPAL_ERR_OUT_OF_RESOURCE; - } - } - - /* Build up the full name */ - len = 16; - if (NULL != syn_type_name) { - len += strlen(syn_type_name); - } - if (NULL != syn_component_name) { - len += strlen(syn_component_name); - } - if (NULL != syn_param_name) { - len += strlen(syn_param_name); - } - si->si_full_name = (char*) malloc(len); - if (NULL == si->si_full_name) { - OBJ_RELEASE(si); - return OPAL_ERR_OUT_OF_RESOURCE; - } - - /* Copy the name over in parts */ - si->si_full_name[0] = '\0'; - if (NULL != syn_type_name) { - strncat(si->si_full_name, syn_type_name, len); - } - if (NULL != syn_component_name) { - if ('\0' != si->si_full_name[0]) { - strcat(si->si_full_name, "_"); - } - strcat(si->si_full_name, syn_component_name); - } - if (NULL != syn_param_name) { - if ('\0' != si->si_full_name[0]) { - strcat(si->si_full_name, "_"); - } - strcat(si->si_full_name, syn_param_name); - } - - /* Create the environment name */ - len = strlen(si->si_full_name) + strlen(mca_prefix) + 16; - si->si_env_var_name = (char*) malloc(len); - if (NULL == si->si_env_var_name) { - OBJ_RELEASE(si); - return OPAL_ERR_OUT_OF_RESOURCE; - } - snprintf(si->si_env_var_name, len, "%s%s", mca_prefix, - si->si_full_name); - - /* Find the param entry; add this syn_info to its list of - synonyms */ - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - - /* Sanity check. Is this a valid parameter? */ - if (MCA_BASE_PARAM_TYPE_MAX <= array[index_orig].mbp_type) { - OBJ_RELEASE(si); - return OPAL_ERROR; - } - - if (NULL == array[index_orig].mbp_synonyms) { - array[index_orig].mbp_synonyms = OBJ_NEW(opal_list_t); - } - opal_list_append(array[index_orig].mbp_synonyms, &(si->super)); - - /* All done */ - - return OPAL_SUCCESS; -} - - -/* - * Set an override - */ -static bool param_set_override(size_t index, - mca_base_param_storage_t *storage, - mca_base_param_type_t type) -{ - size_t size; - mca_base_param_t *array; - - /* Lookup the index and see if it's valid */ - - if (!initialized) { - return false; - } - size = opal_value_array_get_size(&mca_base_params); - if (index > size) { - return false; - } - - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - if (MCA_BASE_PARAM_TYPE_INT == type) { - array[index].mbp_override_value.intval = storage->intval; - } else if (MCA_BASE_PARAM_TYPE_STRING == type) { - if (NULL != storage->stringval) { - array[index].mbp_override_value.stringval = - strdup(storage->stringval); - } else { - array[index].mbp_override_value.stringval = NULL; - } - } else { - return false; - } - - array[index].mbp_override_value_set = true; - - return true; -} - -/* - * Lookup the type of a parameter from an index - */ -static mca_base_param_type_t param_type_from_index (size_t index) -{ - mca_base_param_t *array; - size_t size; - - /* Lookup the index and see if it's valid */ - - if (!initialized) { - return false; - } - size = opal_value_array_get_size(&mca_base_params); - if (index > size) { - return false; - } - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - - return array[index].mbp_type; -} - -/* - * Lookup a parameter in multiple places - */ -static bool param_lookup(size_t index, mca_base_param_storage_t *storage, - mca_base_param_source_t *source_param, - char **source_file) -{ - size_t size; - mca_base_param_t *array; - char *p, *q; - mca_base_param_source_t source = MCA_BASE_PARAM_SOURCE_MAX; - - /* default the value */ - if (NULL != source_file) { - *source_file = NULL; - } - - /* Lookup the index and see if it's valid */ - - if (!initialized) { - return false; - } - size = opal_value_array_get_size(&mca_base_params); - if (index > size) { - return false; - } - array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t); - - /* Ensure that MCA param has a good type */ - - if (MCA_BASE_PARAM_TYPE_INT != array[index].mbp_type && - MCA_BASE_PARAM_TYPE_STRING != array[index].mbp_type) { - return false; - } - - /* Check all the places that the param may be hiding, in priority - order -- but if read_only is true, then only look at the - default location. */ - - if (array[index].mbp_read_only) { - if (lookup_override(&array[index], storage) || - lookup_env(&array[index], storage) || - lookup_file(&array[index], storage, source_file)) { - opal_show_help("help-mca-param.txt", "read-only-param-set", - true, array[index].mbp_full_name); - } - - /* First look at the "real" name of this param */ - if (lookup_default(&array[index], storage)) { - source = MCA_BASE_PARAM_SOURCE_DEFAULT; - } - } else { - if (lookup_override(&array[index], storage)) { - source = MCA_BASE_PARAM_SOURCE_OVERRIDE; - } else if (lookup_env(&array[index], storage)) { - source = MCA_BASE_PARAM_SOURCE_ENV; - } else if (lookup_file(&array[index], storage, source_file)) { - source = MCA_BASE_PARAM_SOURCE_FILE; - } else if (lookup_default(&array[index], storage)) { - source = MCA_BASE_PARAM_SOURCE_DEFAULT; - } - } - if (MCA_BASE_PARAM_SOURCE_MAX != source) { - if (NULL != source_param) { - *source_param = source; - } - - /* If we're returning a string, replace all instances of "~/" - with the user's home directory */ - - if (MCA_BASE_PARAM_TYPE_STRING == array[index].mbp_type && - NULL != storage->stringval) { - if (0 == strncmp(storage->stringval, "~/", 2)) { - if( NULL == home ) { - asprintf(&p, "%s", storage->stringval + 2); - } else { - p = opal_os_path( false, home, storage->stringval + 2, NULL ); - } - free(storage->stringval); - storage->stringval = p; - } - - p = strstr(storage->stringval, ":~/"); - while (NULL != p) { - *p = '\0'; - if( NULL == home ) { - asprintf(&q, "%s:%s", storage->stringval, p + 2); - } else { - asprintf(&q, "%s:%s%s", storage->stringval, home, p + 2); - } - free(storage->stringval); - storage->stringval = q; - p = strstr(storage->stringval, ":~/"); - } - } - - return true; - } - - /* Didn't find it. Doh! */ - - return false; -} - - -/* - * Lookup a param in the overrides section - */ -static bool lookup_override(mca_base_param_t *param, - mca_base_param_storage_t *storage) -{ - if (param->mbp_override_value_set) { - if (MCA_BASE_PARAM_TYPE_INT == param->mbp_type) { - storage->intval = param->mbp_override_value.intval; - } else if (MCA_BASE_PARAM_TYPE_STRING == param->mbp_type) { - storage->stringval = strdup(param->mbp_override_value.stringval); - } - - return true; - } - - /* Don't have an override */ - - return false; -} - - -/* - * Lookup a param in the environment - */ -static bool lookup_env(mca_base_param_t *param, - mca_base_param_storage_t *storage) -{ - char *env = NULL; - opal_list_item_t *item; - syn_info_t *si; - char *deprecated_name = NULL; - bool print_deprecated_warning = false; - - /* Look for the primary param name */ - if (NULL != param->mbp_env_var_name) { - env = getenv(param->mbp_env_var_name); - print_deprecated_warning = - param->mbp_deprecated & !param->mbp_deprecated_warning_shown; - deprecated_name = param->mbp_full_name; - /* Regardless of whether we want to show the deprecated - warning or not, we can skip this check the next time - through on this parameter */ - param->mbp_deprecated_warning_shown = true; - } - - /* If we didn't find the primary name, look in all the synonyms */ - if (NULL == env && NULL != param->mbp_synonyms && - !opal_list_is_empty(param->mbp_synonyms)) { - for (item = opal_list_get_first(param->mbp_synonyms); - NULL == env && opal_list_get_end(param->mbp_synonyms) != item; - item = opal_list_get_next(item)) { - si = (syn_info_t*) item; - env = getenv(si->si_env_var_name); - if (NULL != env && - ((si->si_deprecated && - !si->si_deprecated_warning_shown) || - (param->mbp_deprecated && - !param->mbp_deprecated_warning_shown))) { - print_deprecated_warning = - si->si_deprecated_warning_shown = - param->mbp_deprecated_warning_shown = true; - deprecated_name = si->si_full_name; - } - } - } - - /* If we found it, react */ - if (NULL != env) { - if (MCA_BASE_PARAM_TYPE_INT == param->mbp_type) { - storage->intval = (int)strtol(env,(char**)NULL,0); - } else if (MCA_BASE_PARAM_TYPE_STRING == param->mbp_type) { - storage->stringval = strdup(env); - } - - if (print_deprecated_warning) { - opal_show_help("help-mca-param.txt", "deprecated mca param env", - true, deprecated_name); - } - return true; - } - - /* Didn't find it */ - return false; -} - - -/* - * Lookup a param in the files - */ -static bool lookup_file(mca_base_param_t *param, - mca_base_param_storage_t *storage, - char **source_file) -{ - bool found = false; - syn_info_t *si; - char *deprecated_name = NULL; - opal_list_item_t *item, *in_item; - mca_base_param_file_value_t *fv; - bool print_deprecated_warning = false; - - /* See if we previously found a match from a file. If so, just - return that */ - - if (param->mbp_file_value_set) { - if (NULL != source_file) { - *source_file = param->mbp_source_file; - } - return set(param->mbp_type, storage, ¶m->mbp_file_value); - } - - /* Scan through the list of values read in from files and try to - find a match. If we do, cache it on the param (for future - lookups) and save it in the storage. */ - - for (item = opal_list_get_first(&mca_base_param_file_values); - opal_list_get_end(&mca_base_param_file_values) != item; - item = opal_list_get_next(item)) { - fv = (mca_base_param_file_value_t *) item; - /* If it doesn't match the parameter's real name, check its - synonyms */ - if (0 == strcmp(fv->mbpfv_param, param->mbp_full_name)) { - found = true; - print_deprecated_warning = - param->mbp_deprecated & !param->mbp_deprecated_warning_shown; - deprecated_name = param->mbp_full_name; - /* Regardless of whether we want to show the deprecated - warning or not, we can skip this check the next time - through on this parameter */ - param->mbp_deprecated_warning_shown = true; - } else if (NULL != param->mbp_synonyms && - !opal_list_is_empty(param->mbp_synonyms)) { - /* Check all the synonyms on this parameter and see if the - file value matches */ - for (in_item = opal_list_get_first(param->mbp_synonyms); - opal_list_get_end(param->mbp_synonyms) != in_item; - in_item = opal_list_get_next(in_item)) { - si = (syn_info_t*) in_item; - if (0 == strcmp(fv->mbpfv_param, si->si_full_name)) { - found = true; - if ((si->si_deprecated && - !si->si_deprecated_warning_shown) || - (param->mbp_deprecated && - !param->mbp_deprecated_warning_shown)) { - print_deprecated_warning = - si->si_deprecated_warning_shown = - param->mbp_deprecated_warning_shown = true; - deprecated_name = si->si_full_name; - } - } - } - } - - /* Did we find it? */ - if (found) { - if (MCA_BASE_PARAM_TYPE_INT == param->mbp_type) { - if (NULL != fv->mbpfv_value) { - param->mbp_file_value.intval = - (int)strtol(fv->mbpfv_value,(char**)NULL,0); - } else { - param->mbp_file_value.intval = 0; - } - } else { - param->mbp_file_value.stringval = fv->mbpfv_value; - fv->mbpfv_value = NULL; - } - if (NULL != fv->mbpfv_file) { - param->mbp_source_file = strdup(fv->mbpfv_file); - } - param->mbp_file_value_set = true; - - /* If the caller requested to know what file we found the - value in, give them a copy of the filename pointer */ - if (NULL != source_file) { - *source_file = param->mbp_source_file; - } - - /* Since this is now cached on the param, we might as well - remove it from the list and make future file lookups - faster */ - - opal_list_remove_item(&mca_base_param_file_values, - (opal_list_item_t *) fv); - OBJ_RELEASE(fv); - - /* Print the deprecated warning, if applicable */ - if (print_deprecated_warning) { - opal_show_help("help-mca-param.txt", - "deprecated mca param file", - true, deprecated_name); - } - - return set(param->mbp_type, storage, ¶m->mbp_file_value); - } - } - - return false; -} - - -/* - * Return the default value for a param - */ -static bool lookup_default(mca_base_param_t *param, - mca_base_param_storage_t *storage) -{ - return set(param->mbp_type, storage, ¶m->mbp_default_value); -} - - -static bool set(mca_base_param_type_t type, - mca_base_param_storage_t *dest, mca_base_param_storage_t *src) -{ - switch (type) { - case MCA_BASE_PARAM_TYPE_INT: - dest->intval = src->intval; - break; - - case MCA_BASE_PARAM_TYPE_STRING: - if (NULL != src->stringval) { - dest->stringval = strdup(src->stringval); - } else { - dest->stringval = NULL; - } - break; - - default: - return false; - break; - } - - return true; -} - - -/* * Create an empty param container */ static void param_constructor(mca_base_param_t *p) { - p->mbp_type = MCA_BASE_PARAM_TYPE_MAX; - p->mbp_internal = false; - p->mbp_read_only = false; - p->mbp_deprecated = false; - p->mbp_deprecated_warning_shown = false; - - p->mbp_type_name = NULL; - p->mbp_component_name = NULL; - p->mbp_param_name = NULL; - p->mbp_full_name = NULL; - p->mbp_help_msg = NULL; - - p->mbp_env_var_name = NULL; - - p->mbp_default_value.stringval = NULL; - p->mbp_file_value_set = false; - p->mbp_file_value.stringval = NULL; - p->mbp_source_file = NULL; - p->mbp_override_value_set = false; - p->mbp_override_value.stringval = NULL; - - p->mbp_synonyms = NULL; + memset ((char *) p + sizeof (p->super), 0, sizeof (*p) - sizeof (p->super)); } @@ -1967,85 +651,16 @@ */ static void param_destructor(mca_base_param_t *p) { - opal_list_item_t *item; - - if (NULL != p->mbp_type_name) { - free(p->mbp_type_name); + if (NULL != p->param_value) { + free (p->param_value); } - if (NULL != p->mbp_component_name) { - free(p->mbp_component_name); - } - if (NULL != p->mbp_param_name) { - free(p->mbp_param_name); - } - if (NULL != p->mbp_env_var_name) { - free(p->mbp_env_var_name); - } - if (NULL != p->mbp_full_name) { - free(p->mbp_full_name); - } - if (NULL != p->mbp_help_msg) { - free(p->mbp_help_msg); - } - if (MCA_BASE_PARAM_TYPE_STRING == p->mbp_type) { - if (NULL != p->mbp_default_value.stringval) { - free(p->mbp_default_value.stringval); - } - if (p->mbp_file_value_set) { - if (NULL != p->mbp_file_value.stringval) { - free(p->mbp_file_value.stringval); - } - if (NULL != p->mbp_source_file) { - free(p->mbp_source_file); - } - } - if (p->mbp_override_value_set && - NULL != p->mbp_override_value.stringval) { - free(p->mbp_override_value.stringval); - } - } - /* Destroy any synonyms that are on the list */ - if (NULL != p->mbp_synonyms) { - for (item = opal_list_remove_first(p->mbp_synonyms); - NULL != item; item = opal_list_remove_first(p->mbp_synonyms)) { - OBJ_RELEASE(item); - } - OBJ_RELEASE(p->mbp_synonyms); - } - - /* mark this parameter as invalid */ - p->mbp_type = MCA_BASE_PARAM_TYPE_MAX; - #if OPAL_ENABLE_DEBUG /* Cheap trick to reset everything to NULL */ param_constructor(p); #endif } - -static void fv_constructor(mca_base_param_file_value_t *f) -{ - f->mbpfv_param = NULL; - f->mbpfv_value = NULL; - f->mbpfv_file = NULL; -} - - -static void fv_destructor(mca_base_param_file_value_t *f) -{ - if (NULL != f->mbpfv_param) { - free(f->mbpfv_param); - } - if (NULL != f->mbpfv_value) { - free(f->mbpfv_value); - } - if (NULL != f->mbpfv_file) { - free(f->mbpfv_file); - } - fv_constructor(f); -} - static void info_constructor(mca_base_param_info_t *p) { p->mbpp_index = -1; @@ -2062,7 +677,6 @@ p->mbpp_synonyms_len = 0; p->mbpp_synonym_parent = NULL; - p->mbpp_read_only = false; p->mbpp_help_msg = NULL; } @@ -2077,34 +691,6 @@ info_constructor(p); } -static void syn_info_constructor(syn_info_t *si) -{ - si->si_type_name = si->si_component_name = si->si_param_name = - si->si_full_name = si->si_env_var_name = NULL; - si->si_deprecated = si->si_deprecated_warning_shown = false; -} - -static void syn_info_destructor(syn_info_t *si) -{ - if (NULL != si->si_type_name) { - free(si->si_type_name); - } - if (NULL != si->si_component_name) { - free(si->si_component_name); - } - if (NULL != si->si_param_name) { - free(si->si_param_name); - } - if (NULL != si->si_full_name) { - free(si->si_full_name); - } - if (NULL != si->si_env_var_name) { - free(si->si_env_var_name); - } - - syn_info_constructor(si); -} - int mca_base_param_find_int(const mca_base_component_t *component, const char *param_name, char **env, @@ -2219,35 +805,6 @@ return rc; } -static char *source_name(mca_base_param_source_t source, - const char *filename) -{ - char *ret; - - switch (source) { - case MCA_BASE_PARAM_SOURCE_DEFAULT: - return strdup("default value"); - break; - - case MCA_BASE_PARAM_SOURCE_ENV: - return strdup("command line or environment variable"); - break; - - case MCA_BASE_PARAM_SOURCE_FILE: - asprintf(&ret, "file (%s)", filename); - return ret; - break; - - case MCA_BASE_PARAM_SOURCE_OVERRIDE: - return strdup("internal override"); - break; - - default: - return strdup("unknown (!)"); - break; - } -} - int mca_base_param_check_exclusive_string(const char *type_a, const char *component_a, const char *param_a, @@ -2255,81 +812,7 @@ const char *component_b, const char *param_b) { - int i, ret; - mca_base_param_source_t source_a, source_b; - char *filename_a, *filename_b; - - i = mca_base_param_find(type_a, component_a, param_a); - if (i < 0) { - return OPAL_ERR_NOT_FOUND; - } - ret = mca_base_param_lookup_source(i, &source_a, &filename_a); - if (OPAL_SUCCESS != ret) { - return ret; - } - - i = mca_base_param_find(type_b, component_b, param_b); - if (i < 0) { - return OPAL_ERR_NOT_FOUND; - } - ret = mca_base_param_lookup_source(i, &source_b, &filename_b); - if (OPAL_SUCCESS != ret) { - return ret; - } - - if (MCA_BASE_PARAM_SOURCE_DEFAULT != source_a && - MCA_BASE_PARAM_SOURCE_DEFAULT != source_b) { - size_t len; - char *str_a, *str_b, *name_a, *name_b; - - /* Form cosmetic string names for A */ - str_a = source_name(source_a, filename_a); - len = 5; - if (NULL != type_a) len += strlen(type_a); - if (NULL != component_a) len += strlen(component_a); - if (NULL != param_a) len += strlen(param_a); - name_a = calloc(1, len); - if (NULL == name_a) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - if (NULL != type_a) { - strncat(name_a, type_a, len); - strncat(name_a, "_", len); - } - if (NULL != component_a) strncat(name_a, component_a, len); - strncat(name_a, "_", len); - strncat(name_a, param_a, len); - - /* Form cosmetic string names for B */ - str_b = source_name(source_b, filename_b); - len = 5; - if (NULL != type_b) len += strlen(type_b); - if (NULL != component_b) len += strlen(component_b); - if (NULL != param_b) len += strlen(param_b); - name_b = calloc(1, len); - if (NULL == name_b) { - return OPAL_ERR_OUT_OF_RESOURCE; - } - if (NULL != type_b) { - strncat(name_b, type_b, len); - strncat(name_b, "_", len); - } - if (NULL != component_b) strncat(name_b, component_b, len); - strncat(name_b, "_", len); - strncat(name_b, param_b, len); - - /* Print it all out */ - opal_show_help("help-mca-param.txt", - "mutually exclusive params", - true, name_a, str_a, name_b, str_b); - - /* Free the temp strings */ - free(str_a); - free(name_a); - free(str_b); - free(name_b); - return OPAL_ERR_BAD_PARAM; - } - - return OPAL_SUCCESS; + return mca_base_var_check_exclusive (NULL, type_a, component_a, + param_a, type_b, component_b, + param_b); } Index: opal/mca/base/mca_base_param.h =================================================================== --- opal/mca/base/mca_base_param.h (revision 28004) +++ opal/mca/base/mca_base_param.h (working copy) @@ -18,6 +18,9 @@ */ /** @file + * \deprecated The entire mca_base_param system has been deprectated for + * 1.7 (removed in 1.9). Please use the mca_base_var system instead. + * * This file presents the MCA parameter interface. * * Note that there are two scopes for MCA parameters: "normal" and @@ -108,13 +111,13 @@ mca_base_param_type_t mbpp_type; /** String name of the type of this component */ - char *mbpp_type_name; + const char *mbpp_type_name; /** String name of the component of the parameter */ - char *mbpp_component_name; + const char *mbpp_component_name; /** String name of the parameter of the parameter */ - char *mbpp_param_name; + const char *mbpp_param_name; /** Full, assembled parameter name */ - char *mbpp_full_name; + const char *mbpp_full_name; /** Is this parameter deprecated? */ bool mbpp_deprecated; @@ -132,7 +135,7 @@ /** Is this parameter changable? */ bool mbpp_read_only; /** Help message associated with this parameter */ - char *mbpp_help_msg; + const char *mbpp_help_msg; }; /** * Convenience typedef @@ -159,7 +162,7 @@ * invoked internally (by mca_base_open()) and is only documented * here for completeness. */ - OPAL_DECLSPEC int mca_base_param_init(void); + OPAL_DECLSPEC int mca_base_param_init(void) __opal_attribute_deprecated__; /** * Recache the MCA param files @@ -169,7 +172,7 @@ * @retval OPAL_SUCCESS * */ - OPAL_DECLSPEC int mca_base_param_recache_files(bool rel_path_search); + OPAL_DECLSPEC int mca_base_param_recache_files(bool rel_path_search) __opal_attribute_deprecated__; /** * Register an integer MCA parameter. @@ -229,7 +232,7 @@ bool internal, bool read_only, int default_value, - int *current_value); + int *current_value) __opal_attribute_deprecated__; /** * Register an integer MCA parameter that is not associated with a @@ -291,7 +294,7 @@ bool internal, bool read_only, int default_value, - int *current_value); + int *current_value) __opal_attribute_deprecated__; /** * Register a string MCA parameter. @@ -335,7 +338,7 @@ bool internal, bool read_only, const char *default_value, - char **current_value); + char **current_value) __opal_attribute_deprecated__; /** @@ -402,7 +405,7 @@ bool internal, bool read_only, const char *default_value, - char **current_value); + char **current_value) __opal_attribute_deprecated__; /** * Register a synonym name for an MCA parameter. @@ -441,7 +444,7 @@ OPAL_DECLSPEC int mca_base_param_reg_syn(int orignal_index, const mca_base_component_t *syn_component, const char *syn_param_name, - bool deprecated); + bool deprecated) __opal_attribute_deprecated__; /** * Register an MCA parameter synonym that is not associated with a @@ -467,7 +470,7 @@ OPAL_DECLSPEC int mca_base_param_reg_syn_name(int orignal_index, const char *syn_type, const char *syn_param_name, - bool deprecated); + bool deprecated) __opal_attribute_deprecated__; /** * Deregister a MCA parameter @@ -475,7 +478,7 @@ * @param index Index returned from mca_base_param_register_init() * */ - OPAL_DECLSPEC int mca_base_param_deregister(int index); + OPAL_DECLSPEC int mca_base_param_deregister(int index) __opal_attribute_deprecated__; /** * Look up an integer MCA parameter. @@ -493,7 +496,7 @@ * The value of a specific MCA parameter can be looked up using the * return value from mca_base_param_reg_int(). */ - OPAL_DECLSPEC int mca_base_param_lookup_int(int index, int *value); +OPAL_DECLSPEC int mca_base_param_lookup_int(int index, int *value) __opal_attribute_deprecated__; /** * Look up a string MCA parameter. @@ -518,7 +521,7 @@ * The value of a specific MCA parameter can be looked up using the * return value from mca_base_param_reg_string(). */ - OPAL_DECLSPEC int mca_base_param_lookup_string(int index, char **value); +OPAL_DECLSPEC int mca_base_param_lookup_string(int index, char **value) __opal_attribute_deprecated__; /** * Lookup the source of an MCA parameter's value @@ -538,7 +541,7 @@ */ OPAL_DECLSPEC int mca_base_param_lookup_source(int index, mca_base_param_source_t *source, - char **source_file); + const char **source_file) __opal_attribute_deprecated__; /** * Sets an "override" value for an integer MCA parameter. @@ -558,7 +561,7 @@ * This function may be invoked multiple times; each time, the * last "set" value is replaced with the newest value. */ - OPAL_DECLSPEC int mca_base_param_set_int(int index, int value); + OPAL_DECLSPEC int mca_base_param_set_int(int index, int value) __opal_attribute_deprecated__; /** * Sets an "override" value for an string MCA parameter. @@ -582,7 +585,7 @@ * last "set" value is replaced with the newest value (the old * value is discarded). */ - OPAL_DECLSPEC int mca_base_param_set_string(int index, char *value); + OPAL_DECLSPEC int mca_base_param_set_string(int index, char *value) __opal_attribute_deprecated__; /** * Unset a parameter that was previously set by @@ -596,7 +599,7 @@ * Resets previous value that was set (if any) on the given MCA * parameter. */ - OPAL_DECLSPEC int mca_base_param_unset(int index); + OPAL_DECLSPEC int mca_base_param_unset(int index) __opal_attribute_deprecated__; /** * Get the string name corresponding to the MCA parameter @@ -611,7 +614,7 @@ * The string that is returned is owned by the caller; if * appropriate, it must be eventually freed by the caller. */ - OPAL_DECLSPEC char *mca_base_param_env_var(const char *param_name); + OPAL_DECLSPEC char *mca_base_param_env_var(const char *param_name) __opal_attribute_deprecated__; /** * Find the index for an MCA parameter based on its names. @@ -633,7 +636,7 @@ */ OPAL_DECLSPEC int mca_base_param_find(const char *type, const char *component, - const char *param); + const char *param) __opal_attribute_deprecated__; /** * Find an MCA parameter in an env array based on its names. @@ -652,7 +655,7 @@ OPAL_DECLSPEC int mca_base_param_find_int(const mca_base_component_t *component, const char *param_name, char **env, - int *current_value); + int *current_value) __opal_attribute_deprecated__; /** * Find an MCA parameter (in an env array) that is not associated with a @@ -673,7 +676,7 @@ OPAL_DECLSPEC int mca_base_param_find_int_name(const char *type, const char *param_name, char **env, - int *current_value); + int *current_value) __opal_attribute_deprecated__; /** * Find a string MCA parameter in an env array based on its names. * @@ -691,7 +694,7 @@ OPAL_DECLSPEC int mca_base_param_find_string(const mca_base_component_t *component, const char *param_name, char **env, - char **current_value); + char **current_value) __opal_attribute_deprecated__; /** * Find a string MCA parameter (in an env array) that is not associated with a @@ -712,7 +715,7 @@ OPAL_DECLSPEC int mca_base_param_find_string_name(const char *type, const char *param_name, char **env, - char **current_value); + char **current_value) __opal_attribute_deprecated__; /** * Check that two MCA parameters were not both set to non-default @@ -747,7 +750,7 @@ const char *param_a, const char *type_b, const char *component_b, - const char *param_b); + const char *param_b) __opal_attribute_deprecated__; /** * Set the "internal" flag on an MCA parameter to true or false. @@ -768,7 +771,7 @@ * MPI_INIT (at least, they're not displayed by default), thus * keeping them away from prying user eyes. */ - OPAL_DECLSPEC int mca_base_param_set_internal(int index, bool internal); + OPAL_DECLSPEC int mca_base_param_set_internal(int index, bool internal) __opal_attribute_deprecated__; /** * Obtain a list of all the MCA parameters currently defined as @@ -794,7 +797,7 @@ * mca_base_param_dump_release() when finished with the returned * info list to release all associated memory. */ - OPAL_DECLSPEC int mca_base_param_dump(opal_list_t **info, bool internal); + OPAL_DECLSPEC int mca_base_param_dump(opal_list_t **info, bool internal) __opal_attribute_deprecated__; /** * Obtain a list of all the MCA parameters currently defined as @@ -815,7 +818,7 @@ * strings, suitable for using in an environment. */ OPAL_DECLSPEC int mca_base_param_build_env(char ***env, int *num_env, - bool internal); + bool internal) __opal_attribute_deprecated__; /** * Release the memory associated with the info list returned from @@ -834,7 +837,7 @@ * the caller is finished with the info list, invoke this * function and all memory associated with the list will be freed. */ - OPAL_DECLSPEC int mca_base_param_dump_release(opal_list_t *info); + OPAL_DECLSPEC int mca_base_param_dump_release(opal_list_t *info) __opal_attribute_deprecated__; /** * Shut down the MCA parameter system (normally only invoked by the @@ -850,7 +853,7 @@ * when the process is shutting down (e.g., during MPI_FINALIZE). It * is only documented here for completeness. */ - OPAL_DECLSPEC int mca_base_param_finalize(void); + OPAL_DECLSPEC int mca_base_param_finalize(void) __opal_attribute_deprecated__; END_C_DECLS Index: opal/mca/base/mca_base_param_internal.h =================================================================== --- opal/mca/base/mca_base_param_internal.h (revision 28004) +++ opal/mca/base/mca_base_param_internal.h (working copy) @@ -10,6 +10,8 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -37,7 +39,9 @@ #include "opal/class/opal_object.h" #include "opal/class/opal_list.h" +#include "opal/class/opal_value_array.h" #include "opal/mca/base/mca_base_param.h" +#include "opal/mca/base/mca_base_var.h" BEGIN_C_DECLS @@ -53,7 +57,6 @@ char *stringval; } mca_base_param_storage_t; - /** * \internal * @@ -62,62 +65,10 @@ */ struct mca_base_param_t { /** Allow this to be an OPAL OBJ */ - opal_object_t mbp_super; + opal_object_t super; - /** Enum indicating the type of the parameter (integer or string) */ - mca_base_param_type_t mbp_type; - /** String of the type name, or NULL */ - char *mbp_type_name; - /** String of the component name */ - char *mbp_component_name; - /** String of the parameter name */ - char *mbp_param_name; - /** Full parameter name, in case it is not - __ */ - char *mbp_full_name; - - /** List of synonym names for this parameter. This *must* be a - pointer (vs. a plain opal_list_t) because we copy this whole - struct into a new param for permanent storage - (opal_vale_array_append_item()), and the internal pointers in - the opal_list_t will be invalid when that happens. Hence, we - simply keep a pointer to an external opal_list_t. Synonyms - are uncommon enough that this is not a big performance hit. */ - opal_list_t *mbp_synonyms; - - /** Whether this is internal (not meant to be seen / modified by - users) or not */ - bool mbp_internal; - /** Whether this value is changable from the default value that - was registered (e.g., when true, useful for reporting values, - like the value of the GM library that was linked against) */ - bool mbp_read_only; - /** Whether this MCA parameter (*and* all of its synonyms) is - deprecated or not */ - bool mbp_deprecated; - /** Whether the warning message for the deprecated MCA param has - been shown already or not */ - bool mbp_deprecated_warning_shown; - /** Help message associated with this parameter */ - char *mbp_help_msg; - - /** Environment variable name */ - char *mbp_env_var_name; - - /** Default value of the parameter */ - mca_base_param_storage_t mbp_default_value; - - /** Whether or not we have a file value */ - bool mbp_file_value_set; - /** Value of the parameter found in a file */ - mca_base_param_storage_t mbp_file_value; - /** File the value came from */ - char *mbp_source_file; - - /** Whether or not we have an override value */ - bool mbp_override_value_set; - /** Value of the parameter override set via API */ - mca_base_param_storage_t mbp_override_value; + /* Backing store for the variable value */ + mca_base_param_storage_t *param_value; }; /** * \internal @@ -137,35 +88,6 @@ /** * \internal * - * Structure for holding param names and values read in from files. - */ -struct mca_base_param_file_value_t { - /** Allow this to be an OPAL OBJ */ - opal_list_item_t super; - - /** Parameter name */ - char *mbpfv_param; - /** Parameter value */ - char *mbpfv_value; - /** File it came from */ - char *mbpfv_file; -}; -/** - * \internal - * - * Convenience typedef - */ -typedef struct mca_base_param_file_value_t mca_base_param_file_value_t; - -/** - * Object declaration for mca_base_param_file_value_t - */ -OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_param_file_value_t); - - -/** - * \internal - * * Global list of params and values read in from MCA parameter files */ OPAL_DECLSPEC extern opal_list_t mca_base_param_file_values; @@ -175,7 +97,7 @@ * * Parse a parameter file. */ -OPAL_DECLSPEC int mca_base_parse_paramfile(const char *paramfile); +OPAL_DECLSPEC int mca_base_parse_paramfile(const char *paramfile, opal_list_t *list); END_C_DECLS Index: opal/mca/base/mca_base_parse_paramfile.c =================================================================== --- opal/mca/base/mca_base_parse_paramfile.c (revision 28004) +++ opal/mca/base/mca_base_parse_paramfile.c (working copy) @@ -9,6 +9,8 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2013 Los Alamos National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -24,58 +26,53 @@ #include "opal/class/opal_list.h" #include "opal/mca/mca.h" #include "opal/mca/base/base.h" -#include "opal/mca/base/mca_base_param_internal.h" +#include "opal/mca/base/mca_base_vari.h" #include "opal/util/keyval_parse.h" static void save_value(const char *name, const char *value); static char * file_being_read; +static opal_list_t * _param_list; -int mca_base_parse_paramfile(const char *paramfile) +int mca_base_parse_paramfile(const char *paramfile, opal_list_t *list) { file_being_read = (char*)paramfile; - + _param_list = list; + return opal_util_keyval_parse(paramfile, save_value); } static void save_value(const char *name, const char *value) { - opal_list_item_t *item; - mca_base_param_file_value_t *fv; + mca_base_var_file_value_t *fv; + bool found = false; /* First traverse through the list and ensure that we don't already have a param of this name. If we do, just replace the value. */ - for (item = opal_list_get_first(&mca_base_param_file_values); - opal_list_get_end(&mca_base_param_file_values) != item; - item = opal_list_get_next(item)) { - fv = (mca_base_param_file_value_t *) item; - if (0 == strcmp(name, fv->mbpfv_param)) { - if (NULL != fv->mbpfv_value ) { - free(fv->mbpfv_value); + OPAL_LIST_FOREACH(fv, _param_list, mca_base_var_file_value_t) { + if (0 == strcmp(name, fv->mbvfv_var)) { + if (NULL != fv->mbvfv_value) { + free (fv->mbvfv_value); } - if (NULL != value) { - fv->mbpfv_value = strdup(value); - } else { - fv->mbpfv_value = NULL; - } - fv->mbpfv_file = strdup(file_being_read); - return; + free (fv->mbvfv_file); + found = true; + break; } } - /* We didn't already have the param, so append it to the list */ + if (!found) { + /* We didn't already have the param, so append it to the list */ + fv = OBJ_NEW(mca_base_var_file_value_t); + if (NULL == fv) { + return; + } - fv = OBJ_NEW(mca_base_param_file_value_t); - if (NULL != fv) { - fv->mbpfv_param = strdup(name); - if (NULL != value) { - fv->mbpfv_value = strdup(value); - } else { - fv->mbpfv_value = NULL; - } - fv->mbpfv_file = strdup(file_being_read); - opal_list_append(&mca_base_param_file_values, (opal_list_item_t*) fv); + fv->mbvfv_var = strdup(name); + opal_list_append(_param_list, &fv->super); } + + fv->mbvfv_value = value ? strdup(value) : NULL; + fv->mbvfv_file = strdup(file_being_read); } Index: opal/mca/base/mca_base_var.c =================================================================== --- opal/mca/base/mca_base_var.c (revision 0) +++ opal/mca/base/mca_base_var.c (working copy) @@ -0,0 +1,1873 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2012 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#include + +#include "opal/mca/installdirs/installdirs.h" +#include "opal/util/os_path.h" +#include "opal/util/path.h" +#include "opal/class/opal_value_array.h" +#include "opal/class/opal_pointer_array.h" +#include "opal/util/show_help.h" +#include "opal/util/printf.h" +#include "opal/util/argv.h" +#include "opal/mca/mca.h" +#include "opal/mca/base/mca_base_vari.h" +#include "opal/constants.h" +#include "opal/util/output.h" +#include "opal/util/opal_environ.h" +#include "opal/runtime/opal.h" + +/* + * local variables + */ +static opal_pointer_array_t mca_base_vars; +static opal_pointer_array_t mca_base_var_groups; +static int mca_base_var_groups_timestamp = 0; +static const char *mca_prefix = "OMPI_MCA_"; +static char *home = NULL; +static char *cwd = NULL; +static bool initialized = false; +static char * force_agg_path = NULL; +static char *mca_base_var_files = NULL; +static char *mca_base_var_override_file = NULL; +static char *mca_base_var_file_prefix = NULL; +static char *mca_base_param_file_path = NULL; +static bool mca_base_var_suppress_override_warning = false; +static opal_list_t mca_base_var_file_values; +static opal_list_t mca_base_var_override_values; + +static int mca_base_var_count = 0; +static int mca_base_var_group_count = 0; + +/* + * local functions + */ +static int fixup_files(char **file_list, char * path, bool rel_path_search); +static int read_files (char *file_list, opal_list_t *file_values); +static int mca_base_var_cache_files (bool rel_path_search); +static int var_set_initial (mca_base_var_t *var); +static int var_get (int index, mca_base_var_t **var_out, bool original); + +/* + * classes + */ +static void var_constructor (mca_base_var_t *p); +static void var_destructor (mca_base_var_t *p); +OBJ_CLASS_INSTANCE(mca_base_var_t, opal_object_t, + var_constructor, var_destructor); + +static void fv_constructor (mca_base_var_file_value_t *p); +static void fv_destructor (mca_base_var_file_value_t *p); +OBJ_CLASS_INSTANCE(mca_base_var_file_value_t, opal_list_item_t, + fv_constructor, fv_destructor); + +static void mca_base_var_group_constructor (mca_base_var_group_t *group); +static void mca_base_var_group_destructor (mca_base_var_group_t *group); +OBJ_CLASS_INSTANCE(mca_base_var_group_t, opal_object_t, + mca_base_var_group_constructor, + mca_base_var_group_destructor); + +OBJ_CLASS_INSTANCE(mca_base_var_enum_t, opal_object_t, NULL, NULL); + +/* + * Generate a full name from three names + */ +static int mca_base_var_generate_full_name4 (const char *project, const char *framework, const char *component, + const char *variable, char **full_name) +{ + const char * const names[] = {project, framework, component, variable}; + size_t cur_len, i, len; + char *name, *tmp; + + *full_name = NULL; + + for (i = 0, len = 0 ; i < 4 ; ++i) { + if (NULL != names[i]) { + /* Add space for the string + _ or \0 */ + len += strlen (names[i]) + 1; + } + } + + name = calloc (1, len); + if (NULL == name) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + for (i = 0, tmp = name ; i < 4 ; ++i) { + if (NULL != names[i]) { + if (name != tmp) { + *tmp++ = '_'; + } + strncat (name, names[i], len - (size_t)(uintptr_t)(tmp - name)); + tmp += strlen (names[i]); + } + } + + *full_name = name; + return OPAL_SUCCESS; +} + +static int compare_strings (const char *str1, const char *str2) { + if (NULL == str1 && NULL == str2) { + return 0; + } + + if (NULL != str1 && NULL != str2) { + return strcmp (str1, str2); + } + + return 1; +} + +/* + * Set it up + */ +int mca_base_var_init(void) +{ + if (!initialized) { + /* Init the value array for the param storage */ + + OBJ_CONSTRUCT(&mca_base_vars, opal_pointer_array_t); + /* These values are arbitrary */ + opal_pointer_array_init (&mca_base_vars, 128, 16384, 128); + + OBJ_CONSTRUCT(&mca_base_var_groups, opal_pointer_array_t); + /* These values are arbitrary */ + opal_pointer_array_init (&mca_base_var_groups, 128, 16384, 128); + + mca_base_var_count = 0; + mca_base_var_group_count = 0; + + /* Init the file param value list */ + + OBJ_CONSTRUCT(&mca_base_var_file_values, opal_list_t); + + OBJ_CONSTRUCT(&mca_base_var_override_values, opal_list_t); + + /* Set this before we register the parameter, below */ + + initialized = true; + + mca_base_var_cache_files(false); + } + + return OPAL_SUCCESS; +} + +static int mca_base_var_cache_files(bool rel_path_search) +{ + int ret; + + /* We may need this later */ + home = (char*)opal_home_directory(); + + if(NULL == cwd) { + cwd = (char *) malloc(sizeof(char) * MAXPATHLEN); + if( NULL == (cwd = getcwd(cwd, MAXPATHLEN) )) { + opal_output(0, "Error: Unable to get the current working directory\n"); + cwd = strdup("."); + } + } + +#if OPAL_WANT_HOME_CONFIG_FILES + asprintf(&mca_base_var_files, "%s"OPAL_PATH_SEP".openmpi" OPAL_PATH_SEP + "mca-params.conf%c%s" OPAL_PATH_SEP "openmpi-mca-params.conf", + home, OPAL_ENV_SEP, opal_install_dirs.sysconfdir); +#else + asprintf(&mca_base_var_files, "%s" OPAL_PATH_SEP "openmpi-mca-params.conf", + opal_install_dirs.sysconfdir); +#endif + + /* Initialize a parameter that says where MCA param files can be found. + We may change this value so set the scope to MCA_BASE_VAR_SCOPE_READONLY */ + ret = mca_base_var_register ("opal", "mca", "base", "param_files", "Path for MCA " + "configuration files containing variable values", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, MCA_BASE_VAR_VERBOSITY_USER_DETAIL, + MCA_BASE_VAR_SCOPE_READONLY, &mca_base_var_files); + if (OPAL_SUCCESS != ret) { + return ret; + } + + (void) mca_base_var_register_synonym (ret, "opal", "mca", NULL, "param_files", + MCA_BASE_VAR_SYN_FLAG_DEPRECATED); + + ret = asprintf(&mca_base_var_override_file, "%s" OPAL_PATH_SEP "openmpi-mca-params-override.conf", + opal_install_dirs.sysconfdir); + if (0 > ret) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + ret = mca_base_var_register ("opal", "mca", "base", "override_param_file", + "Variables set in this file will override any value set in" + "the environment or another configuration file", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, MCA_BASE_VAR_FLAG_DEFAULT_ONLY, + MCA_BASE_VAR_VERBOSITY_USER_DETAIL, MCA_BASE_VAR_SCOPE_CONSTANT, + &mca_base_var_override_file); + if (0 > ret) { + return ret; + } + + /* Disable reading MCA parameter files. */ + if (0 == strcmp (mca_base_var_files, "none")) { + return OPAL_SUCCESS; + } + + mca_base_var_suppress_override_warning = false; + ret = mca_base_var_register ("opal", "mca", "base", "suppress_override_warning", + "Suppress warnings when attempting to set an overridden value (default: false)", + MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, MCA_BASE_VAR_VERBOSITY_USER_DETAIL, + MCA_BASE_VAR_SCOPE_LOCAL, &mca_base_var_suppress_override_warning); + + /* Aggregate MCA parameter files + * A prefix search path to look up aggregate MCA parameter file + * requests that do not specify an absolute path + */ + ret = mca_base_var_register ("opal", "mca", "base", "param_file_prefix", + "Aggregate MCA parameter file sets", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, MCA_BASE_VAR_VERBOSITY_USER_ALL, + MCA_BASE_VAR_SCOPE_READONLY, &mca_base_var_file_prefix); + + ret = asprintf(&mca_base_param_file_path, "%s" OPAL_PATH_SEP "amca-param-sets%c%s", + opal_install_dirs.pkgdatadir, OPAL_ENV_SEP, cwd); + if (0 > ret) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + ret = mca_base_var_register ("opal", "mca", "base", "param_file_path", + "Aggregate MCA parameter Search path", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, MCA_BASE_VAR_VERBOSITY_USER_ALL, + MCA_BASE_VAR_SCOPE_READONLY, &mca_base_param_file_path); + if (0 > ret) { + return ret; + } + + force_agg_path = NULL; + ret = mca_base_var_register ("opal", "mca", "base", "param_file_path_force", + "Forced Aggregate MCA parameter Search path", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, MCA_BASE_VAR_VERBOSITY_USER_ALL, + MCA_BASE_VAR_SCOPE_READONLY, &force_agg_path); + if (0 > ret) { + return ret; + } + + if (NULL != force_agg_path) { + if (NULL != mca_base_param_file_path) { + char *tmp_str = mca_base_param_file_path; + + asprintf(&mca_base_param_file_path, "%s%c%s", force_agg_path, OPAL_ENV_SEP, tmp_str); + free(tmp_str); + } else { + mca_base_param_file_path = strdup(force_agg_path); + } + } + + if (NULL != mca_base_var_file_prefix) { + char *tmp_str; + + /* + * Resolve all relative paths. + * the file list returned will contain only absolute paths + */ + if( OPAL_SUCCESS != fixup_files(&mca_base_var_file_prefix, mca_base_param_file_path, rel_path_search) ) { +#if 0 + /* JJH We need to die! */ + abort(); +#else + ; +#endif + } + else { + /* Prepend the files to the search list */ + asprintf(&tmp_str, "%s%c%s", mca_base_var_file_prefix, OPAL_ENV_SEP, mca_base_var_files); + free (mca_base_var_files); + mca_base_var_files = tmp_str; + } + } + + read_files (mca_base_var_files, &mca_base_var_file_values); + + if (0 == access(mca_base_var_override_file, F_OK)) { + read_files (mca_base_var_override_file, &mca_base_var_override_values); + } + + return OPAL_SUCCESS; +} + +static int group_get (const int group_index, mca_base_var_group_t **group, bool invalidok) +{ + if (group_index < 0) { + return OPAL_ERR_NOT_FOUND; + } + + *group = (mca_base_var_group_t *) opal_pointer_array_get_item (&mca_base_var_groups, + group_index); + if (NULL == *group || (!invalidok && !(*group)->group_isvalid)) { + *group = NULL; + return OPAL_ERR_NOT_FOUND; + } + + return OPAL_SUCCESS; +} + +static int group_find (const char *project_name, const char *framework_name, + const char *component_name, bool invalidok) +{ + size_t size, i; + + size = opal_pointer_array_get_size (&mca_base_var_groups); + for (i = 0 ; i < size ; ++i) { + mca_base_var_group_t *group = opal_pointer_array_get_item (&mca_base_var_groups, + i); + + if (NULL != group && 0 == compare_strings (project_name, group->group_project) && + 0 == compare_strings (framework_name, group->group_framework) && + 0 == compare_strings (component_name, group->group_component) && + (group->group_isvalid || invalidok)) { + return (int) i; + } + } + + return OPAL_ERR_NOT_FOUND; +} + +static int group_register (const char *project_name, const char *framework_name, + const char *component_name, const char *description) +{ + mca_base_var_group_t *group; + int group_id, parent_id = -1; + int ret; + + if (NULL == project_name && NULL == framework_name && NULL == component_name) { + /* don't create a group with no name (maybe we should create a generic group?) */ + return -1; + } + + group_id = group_find (project_name, framework_name, component_name, true); + if (0 <= group_id) { + (void) group_get (group_id, &group, true); + group->group_isvalid = true; + mca_base_var_groups_timestamp++; + + /* group already exists. return it's index */ + return group_id; + } + + group = OBJ_NEW(mca_base_var_group_t); + + group->group_isvalid = true; + + if (NULL != project_name) { + group->group_project = strdup (project_name); + if (NULL == group->group_project) { + OBJ_RELEASE(group); + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != framework_name) { + group->group_framework = strdup (framework_name); + if (NULL == group->group_framework) { + OBJ_RELEASE(group); + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != component_name) { + group->group_component = strdup (component_name); + if (NULL == group->group_component) { + OBJ_RELEASE(group); + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + if (NULL != description) { + group->group_description = strdup (description); + if (NULL == group->group_description) { + OBJ_RELEASE(group); + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + + if (NULL != framework_name && NULL != component_name) { + if (component_name) { + parent_id = group_register (project_name, framework_name, NULL, NULL); + } else if (framework_name) { + parent_id = group_register (project_name, NULL, NULL, NULL); + } + } + + /* avoid groups of the form opal_opal, ompi_ompi, etc */ + if (NULL != project_name && NULL != framework_name && + (0 == strcmp (project_name, framework_name))) { + project_name = NULL; + } + + /* build the group name */ + ret = mca_base_var_generate_full_name4 (NULL, project_name, framework_name, component_name, + &group->group_full_name); + if (OPAL_SUCCESS != ret) { + OBJ_RELEASE(group); + return ret; + } + + group_id = opal_pointer_array_add (&mca_base_var_groups, group); + if (0 > group_id) { + OBJ_RELEASE(group); + return OPAL_ERROR; + } + + mca_base_var_group_count++; + mca_base_var_groups_timestamp++; + + if (0 <= parent_id) { + mca_base_var_group_t *parent_group; + + (void) group_get(parent_id, &parent_group, false); + opal_value_array_append_item (&parent_group->group_subgroups, &parent_id); + } + + return group_id; +} + +int mca_base_var_group_register (const char *project_name, const char *framework_name, + const char *component_name, const char *description) +{ + return group_register (project_name, framework_name, component_name, description); +} + +int mca_base_var_group_component_register (const mca_base_component_t *component, + const char *description) +{ + /* 1.7 components do not store the project */ + return group_register (NULL, component->mca_type_name, + component->mca_component_name, description); +} + + +int mca_base_var_group_deregister (int group_index) +{ + mca_base_var_group_t *group; + int size, i, ret; + int *params, *subgroups; + + ret = group_get (group_index, &group, false); + if (OPAL_SUCCESS != ret) { + return ret; + } + + group->group_isvalid = false; + + /* deregister all associated mca parameters */ + size = opal_value_array_get_size(&group->group_vars); + params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + + for (i = 0 ; i < size ; ++i) { + (void) mca_base_var_deregister (params[i]); + } + OBJ_DESTRUCT(&group->group_vars); + OBJ_CONSTRUCT(&group->group_vars, opal_value_array_t); + + size = opal_value_array_get_size(&group->group_subgroups); + subgroups = OPAL_VALUE_ARRAY_GET_BASE(&group->group_subgroups, int); + for (i = 0 ; i < size ; ++i) { + (void) mca_base_var_group_deregister (subgroups[i]); + } + OBJ_DESTRUCT(&group->group_subgroups); + OBJ_CONSTRUCT(&group->group_subgroups, opal_value_array_t); + + mca_base_var_groups_timestamp++; + + return OPAL_SUCCESS; +} + +int mca_base_var_group_find (const char *project_name, + const char *framework_name, + const char *component_name) +{ + return group_find (project_name, framework_name, component_name, false); +} + +static int mca_base_var_group_add_var (const int group_index, const int param_index) +{ + mca_base_var_group_t *group; + int size, i, ret; + int *params; + + ret = group_get (group_index, &group, false); + if (OPAL_SUCCESS != ret) { + return ret; + } + + size = opal_value_array_get_size(&group->group_vars); + params = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + for (i = 0 ; i < size ; ++i) { + if (params[i] == param_index) { + return i; + } + } + + if (OPAL_SUCCESS != + (ret = opal_value_array_append_item (&group->group_vars, ¶m_index))) { + return ret; + } + + mca_base_var_groups_timestamp++; + + /* return the group index */ + return (int) opal_value_array_get_size (&group->group_vars) - 1; +} + +int mca_base_var_group_get (const int group_index, const mca_base_var_group_t **group) +{ + return group_get (group_index, (mca_base_var_group_t **) group, false); +} + +int mca_base_var_group_set_var_flag (const int group_index, mca_base_var_flag_t flags, bool set) +{ + mca_base_var_group_t *group; + int size, i, ret; + int *vars; + + ret = group_get (group_index, &group, false); + if (OPAL_SUCCESS != ret) { + return ret; + } + + /* set the flag on each valid variable */ + size = opal_value_array_get_size(&group->group_vars); + vars = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + + for (i = 0 ; i < size ; ++i) { + if (0 <= vars[i]) { + (void) mca_base_var_set_flag (vars[i], flags, set); + } + } + + return OPAL_SUCCESS; +} + +int mca_base_var_enum_create (char *name, mca_base_var_enum_value_t *values, mca_base_var_enum_t **enumerator) +{ + mca_base_var_enum_t *new_enum; + + *enumerator = NULL; + + new_enum = OBJ_NEW(mca_base_var_enum_t); + if (NULL == new_enum) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + new_enum->enum_name = strdup (name); + if (NULL == new_enum->enum_name) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + new_enum->enum_values = values; + + *enumerator = new_enum; + + return OPAL_SUCCESS; +} + +/* + * Look up an integer MCA parameter. + */ +int mca_base_var_get_value (int index, const void *value, + mca_base_var_source_t *source, + const char **source_file) +{ + mca_base_var_t *var; + void **tmp = (void **) value; + int ret; + + ret = var_get (index, &var, true); + if (OPAL_SUCCESS != ret) { + return ret; + } + + if (!VAR_IS_VALID(var[0])) { + return OPAL_ERR_BAD_PARAM; + } + + if (NULL != value) { + /* Return a poiner to our backing store (either a char **, int *, + or bool *) */ + *tmp = var->mbv_storage; + } + + if (NULL != source) { + *source = var->mbv_source; + } + + if (NULL != source_file) { + *source_file = var->mbv_source_file; + } + + return OPAL_SUCCESS; +} + +static int var_set_int (mca_base_var_t *var, int value) +{ + var->mbv_storage->intval = value; + return OPAL_SUCCESS; +} + +static int var_set_bool (mca_base_var_t *var, bool value) +{ + var->mbv_storage->boolval = value; + return OPAL_SUCCESS; +} + +static int var_set_string (mca_base_var_t *var, char *value) +{ + char *tmp, *p; + int ret; + + if (var->mbv_storage->stringval) { + free (var->mbv_storage->stringval); + } + + var->mbv_storage->stringval = NULL; + + if (NULL == value) { + return OPAL_SUCCESS; + } + + /* Replace all instances of ~/ in a path-style string with the + user's home directory. This may be handled by the enumerator + in the future. */ + if (0 == strncmp (value, "~/", 2)) { + if (NULL != home) { + ret = asprintf (&value, "%s/%s", home, value + 2); + if (0 > ret) { + return OPAL_ERROR; + } + } else { + value = strdup (value + 2); + } + } else { + value = strdup (value); + } + + if (NULL == value) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + while (NULL != (tmp = strstr (value, ":~/"))) { + tmp[0] = '\0'; + tmp += 3; + + ret = asprintf (&tmp, "%s:%s%s%s", p, home ? home : "", home ? "/" : "", tmp); + + free (value); + + if (0 > ret) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + value = tmp; + } + + var->mbv_storage->stringval = value; + + return OPAL_SUCCESS; +} + +static int var_set_from_string (mca_base_var_t *var, char *src) +{ + mca_base_var_storage_t *dst = var->mbv_storage; + int i, value; + bool is_int; + char *tmp; + + memset (dst, 0, sizeof (*dst)); + + if (NULL == src || 0 == strlen (src)) { + return OPAL_SUCCESS; + } + + switch (var->mbv_type) { + case MCA_BASE_VAR_TYPE_INT: + if (var->mbv_enumerator) { + /* Check for an integer value */ + value = strtol (src, &tmp, 0); + is_int = tmp[0] == '\0'; + + for (i = 0 ; var->mbv_enumerator->enum_values[i].string ; ++i) { + if ((is_int && value == var->mbv_enumerator->enum_values[i].value) || + 0 == strcasecmp (src, var->mbv_enumerator->enum_values[i].string)) { + dst->intval = var->mbv_enumerator->enum_values[i].value; + break; + } + } + + /* Check if we found a valid value */ + if (NULL == var->mbv_enumerator->enum_values[i].string) { + opal_show_help("help-mca-var.txt", "invalid-value", + true, var->mbv_full_name, src); + return OPAL_ERR_VALUE_OUT_OF_BOUNDS; + } + } else { + if (0 == strcmp (src, "true")) { + dst->intval = 1; + } else if (0 == strcmp (src, "false")) { + dst->intval = 0; + } else { + errno = 0; + + dst->intval = strtol (src, NULL, 0); + if (0 != errno) { + return OPAL_ERROR; + } + } + } + + break; + case MCA_BASE_VAR_TYPE_BOOL: + if (0 == strcmp (src, "true")) { + dst->boolval = true; + } else if (0 == strcmp (src, "false")) { + dst->boolval = false; + } else { + errno = 0; + + dst->boolval = !!(strtol (src, NULL, 0)); + if (0 != errno) { + return OPAL_ERROR; + } + } + + break; + case MCA_BASE_VAR_TYPE_STRING: + var_set_string (var, src); + break; + case MCA_BASE_VAR_TYPE_MAX: + return OPAL_ERROR; + } + + return OPAL_SUCCESS; +} + +/* + * Set a variable + */ +int mca_base_var_set_value (int index, void *value, size_t size, mca_base_var_source_t source, + const char *source_file) +{ + mca_base_var_t *var; + int ret, i; + + ret = var_get (index, &var, true); + if (OPAL_SUCCESS != ret) { + return ret; + } + + if (!VAR_IS_VALID(var[0])) { + return OPAL_ERR_BAD_PARAM; + } + + if (!VAR_IS_SETTABLE(var[0])) { + return OPAL_ERR_PERM; + } + + /* Does index represent a synonym */ + if (var->mbv_index != index) { + } + + + switch (var->mbv_type) { + case MCA_BASE_VAR_TYPE_INT: + if (NULL != var->mbv_enumerator) { + for (i = 0 ; var->mbv_enumerator->enum_values[i].string ; ++i) { + if (((int *) value)[0] == var->mbv_enumerator->enum_values[i].value) { + break; + } + } + + if (NULL == var->mbv_enumerator->enum_values[i].string) { + return OPAL_ERR_VALUE_OUT_OF_BOUNDS; + } + } + + var_set_int (var, ((int *) value)[0]); + + break; + case MCA_BASE_VAR_TYPE_BOOL: + var_set_bool (var, ((bool *) value)[0]); + break; + case MCA_BASE_VAR_TYPE_STRING: + var_set_string (var, (char *) value); + break; + case MCA_BASE_VAR_TYPE_MAX: + return OPAL_ERR_BAD_PARAM; + } + + var->mbv_source = source; + + if (MCA_BASE_VAR_SOURCE_FILE == source && NULL != source_file) { + free (var->mbv_source_file); + var->mbv_source_file = strdup (source_file); + } + + return OPAL_SUCCESS; +} + +/* + * Deregister a parameter + */ +int mca_base_var_deregister(int index) +{ + mca_base_var_t *var; + int ret; + + ret = var_get (index, &var, false); + if (OPAL_SUCCESS != ret) { + return ret; + } + + if (!VAR_IS_VALID(var[0])) { + return OPAL_ERR_BAD_PARAM; + } + + /* Mark this parameter as invalid but keep its info in case this + parameter is reregistered later */ + var->mbv_flags &= ~MCA_BASE_VAR_FLAG_VALID; + + /* Release the current value if it is a string. */ + if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type && + var->mbv_storage->stringval) { + free (var->mbv_storage->stringval); + var->mbv_storage->stringval = NULL; + } else if (NULL != var->mbv_enumerator) { + OBJ_RELEASE(var->mbv_enumerator); + var->mbv_enumerator = NULL; + } + + return OPAL_SUCCESS; +} + +static int var_get (int index, mca_base_var_t **var_out, bool original) +{ + mca_base_var_t *var; + + if (var_out) { + *var_out = NULL; + } + + /* Check for bozo cases */ + if (!initialized) { + return OPAL_ERROR; + } + + if (index < 0) { + return OPAL_ERR_BAD_PARAM; + } + + var = opal_pointer_array_get_item (&mca_base_vars, index); + if (NULL == var) { + return OPAL_ERR_BAD_PARAM; + } + + if (VAR_IS_SYNONYM(var[0]) && original) { + var = opal_pointer_array_get_item (&mca_base_vars, var->mbv_synonym_for); + } + + if (var_out) { + *var_out = var; + } + + return OPAL_SUCCESS; +} + +int mca_base_var_env_name(const char *param_name, + char **env_name) +{ + int ret; + + assert (NULL != env_name); + + ret = asprintf(env_name, "%s%s", mca_prefix, param_name); + if (0 > ret) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + + return OPAL_SUCCESS; +} + +/* + * Find the index for an MCA parameter based on its names. + */ +static int var_find (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + bool invalidok) +{ + mca_base_var_group_t *group; + size_t i, size; + int group_id; + int *vars; + + /* Check for bozo cases */ + if (!initialized) { + return OPAL_ERROR; + } + + /* Loop through looking for a parameter of a given framework/component/variable */ + group_id = group_find (project_name, framework_name, component_name, false); + if (0 > group_id) { + return OPAL_ERR_NOT_FOUND; + } + + (void) group_get (group_id, &group, false); + + vars = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, int); + size = opal_value_array_get_size(&group->group_vars); + + for (i = 0 ; i < size ; ++i) { + mca_base_var_t *var = NULL; + + (void) var_get (vars[i], &var, false); + if (NULL == var) { + continue; + } + + if ((invalidok || VAR_IS_VALID(var[0])) && + 0 == compare_strings (variable_name, var->mbv_variable_name)) { + return vars[i]; + } + } + + /* Didn't find it */ + return OPAL_ERROR; +} + +/* + * Find the index for an MCA parameter based on its names. + */ +int mca_base_var_find (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name) +{ + return var_find (project_name, framework_name, component_name, variable_name, false); +} + +int mca_base_var_set_flag (int index, mca_base_var_flag_t flag, bool set) +{ + mca_base_var_t *var; + int ret; + + ret = var_get (index, &var, true); + if (OPAL_SUCCESS != ret || VAR_IS_SYNONYM(var[0])) { + return OPAL_ERR_BAD_PARAM; + } + + var->mbv_flags = (var->mbv_flags & ~flag) | (set ? flag : 0); + + /* All done */ + return OPAL_SUCCESS; +} + +/* + * Return info on a parameter at an index + */ +int mca_base_var_get (int index, const mca_base_var_t **var) +{ + return var_get (index, (mca_base_var_t **) var, false); +} + +/* + * Make an argv-style list of strings suitable for an environment + */ +int mca_base_var_build_env(char ***env, int *num_env, bool internal) +{ + mca_base_var_t *var; + size_t i, len; + + /* Check for bozo cases */ + + if (!initialized) { + return OPAL_ERROR; + } + + /* Iterate through all the registered parameters */ + + len = opal_pointer_array_get_size(&mca_base_vars); + for (i = 0; i < len; ++i) { + char *str = NULL; + + var = opal_pointer_array_get_item (&mca_base_vars, i); + if (NULL == var) { + continue; + } + + /* Don't output default values or internal variables (unless + requested) */ + if (MCA_BASE_VAR_SOURCE_DEFAULT == var->mbv_source || + (!internal && VAR_IS_INTERNAL(var[0]))) { + continue; + } + + switch (var->mbv_type) { + case MCA_BASE_VAR_TYPE_INT: + case MCA_BASE_VAR_TYPE_BOOL: + asprintf(&str, "%s%s=%d", mca_prefix, var->mbv_full_name, + var->mbv_storage->intval); + break; + case MCA_BASE_VAR_TYPE_STRING: + if (NULL != var->mbv_storage->stringval) { + asprintf(&str, "%s%s=%s", mca_prefix, var->mbv_full_name, + var->mbv_storage->stringval); + } + break; + case MCA_BASE_VAR_TYPE_MAX: + goto cleanup; + } + + if (NULL != str) { + opal_argv_append(num_env, env, str); + free(str); + } + + switch (var->mbv_source) { + case MCA_BASE_VAR_SOURCE_FILE: + case MCA_BASE_VAR_SOURCE_OVERRIDE: + asprintf (&str, "%sSOURCE_%s=FILE:%s", mca_prefix, var->mbv_full_name, + var->mbv_source_file); + break; + case MCA_BASE_VAR_SOURCE_COMMAND_LINE: + asprintf (&str, "%sSOURCE_%s=COMMAND_LINE", mca_prefix, var->mbv_full_name); + break; + case MCA_BASE_VAR_SOURCE_ENV: + case MCA_BASE_VAR_SOURCE_SET: + case MCA_BASE_VAR_SOURCE_DEFAULT: + str = NULL; + break; + case MCA_BASE_VAR_SOURCE_MAX: + goto cleanup; + } + + if (NULL != str) { + opal_argv_append(num_env, env, str); + free(str); + } + } + + /* All done */ + + return OPAL_SUCCESS; + + /* Error condition */ + + cleanup: + if (*num_env > 0) { + opal_argv_free(*env); + *num_env = 0; + *env = NULL; + } + return OPAL_ERR_NOT_FOUND; +} + +/* + * Shut down the MCA parameter system (normally only invoked by the + * MCA framework itself). + */ +int mca_base_var_finalize(void) +{ + opal_object_t *object; + opal_list_item_t *item; + int size, i; + + if (initialized) { + size = opal_pointer_array_get_size(&mca_base_vars); + for (i = 0 ; i < size ; ++i) { + object = opal_pointer_array_get_item (&mca_base_vars, i); + if (NULL != object) { + OBJ_RELEASE(object); + } + } + OBJ_DESTRUCT(&mca_base_vars); + + while (NULL != + (item = opal_list_remove_first(&mca_base_var_file_values))) { + OBJ_RELEASE(item); + } + OBJ_DESTRUCT(&mca_base_var_file_values); + + while (NULL != + (item = opal_list_remove_first(&mca_base_var_override_values))) { + OBJ_RELEASE(item); + } + OBJ_DESTRUCT(&mca_base_var_override_values); + + if( NULL != cwd ) { + free(cwd); + cwd = NULL; + } + + size = opal_pointer_array_get_size(&mca_base_var_groups); + for (i = 0 ; i < size ; ++i) { + object = opal_pointer_array_get_item (&mca_base_var_groups, + i); + if (NULL != object) { + OBJ_RELEASE(object); + } + } + OBJ_DESTRUCT(&mca_base_var_groups); + + initialized = false; + mca_base_var_count = 0; + mca_base_var_group_count = 0; + } + + /* All done */ + + return OPAL_SUCCESS; +} + + +/*************************************************************************/ +static int fixup_files(char **file_list, char * path, bool rel_path_search) { + int exit_status = OPAL_SUCCESS; + char **files = NULL; + char **search_path = NULL; + char * tmp_file = NULL; + char **argv = NULL; + int mode = R_OK; /* The file exists, and we can read it */ + int count, i, argc = 0; + + search_path = opal_argv_split(path, OPAL_ENV_SEP); + files = opal_argv_split(*file_list, OPAL_ENV_SEP); + count = opal_argv_count(files); + + /* Read in reverse order, so we can preserve the original ordering */ + for (i = 0 ; i < count; ++i) { + /* Absolute paths preserved */ + if ( opal_path_is_absolute(files[i]) ) { + if( NULL == opal_path_access(files[i], NULL, mode) ) { + opal_show_help("help-mca-var.txt", "missing-param-file", + true, getpid(), files[i], path); + exit_status = OPAL_ERROR; + goto cleanup; + } + else { + opal_argv_append(&argc, &argv, files[i]); + } + } + /* Resolve all relative paths: + * - If filename contains a "/" (e.g., "./foo" or "foo/bar") + * - look for it relative to cwd + * - if exists, use it + * - ow warn/error + */ + else if (!rel_path_search && NULL != strchr(files[i], OPAL_PATH_SEP[0]) ) { + if( NULL != force_agg_path ) { + tmp_file = opal_path_access(files[i], force_agg_path, mode); + } + else { + tmp_file = opal_path_access(files[i], cwd, mode); + } + + if( NULL == tmp_file ) { + opal_show_help("help-mca-var.txt", "missing-param-file", + true, getpid(), files[i], cwd); + exit_status = OPAL_ERROR; + goto cleanup; + } + else { + opal_argv_append(&argc, &argv, tmp_file); + } + } + /* Resolve all relative paths: + * - Use path resolution + * - if found and readable, use it + * - otherwise, warn/error + */ + else { + if( NULL != (tmp_file = opal_path_find(files[i], search_path, mode, NULL)) ) { + opal_argv_append(&argc, &argv, tmp_file); + free(tmp_file); + tmp_file = NULL; + } + else { + opal_show_help("help-mca-var.txt", "missing-param-file", + true, getpid(), files[i], path); + exit_status = OPAL_ERROR; + goto cleanup; + } + } + } + + free(*file_list); + *file_list = opal_argv_join(argv, OPAL_ENV_SEP); + + cleanup: + if( NULL != files ) { + opal_argv_free(files); + files = NULL; + } + if( NULL != argv ) { + opal_argv_free(argv); + argv = NULL; + } + if( NULL != search_path ) { + opal_argv_free(search_path); + search_path = NULL; + } + if( NULL != tmp_file ) { + free(tmp_file); + tmp_file = NULL; + } + + return exit_status; +} + +static int read_files(char *file_list, opal_list_t *file_values) +{ + int i, count; + char **files; + + /* Iterate through all the files passed in -- read them in reverse + order so that we preserve unix/shell path-like semantics (i.e., + the entries farthest to the left get precedence) */ + + files = opal_argv_split(file_list, OPAL_ENV_SEP); + count = opal_argv_count(files); + + for (i = count - 1; i >= 0; --i) { + mca_base_parse_paramfile(files[i], file_values); + } + opal_argv_free(files); + + return OPAL_SUCCESS; +} + +/******************************************************************************/ +static int register_variable (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, mca_base_var_type_t type, + mca_base_var_enum_t *enumerator, int bind, + mca_base_var_flag_t flags, mca_base_var_verbosity_t verbosity, + mca_base_var_scope_t scope, int synonym_for, + void *storage) +{ + int ret, var_index, group; + mca_base_var_t *var; + + /* Developer error. Storage can not be NULL and type must exist */ + assert (((flags & MCA_BASE_VAR_FLAG_SYNONYM) || NULL != storage) && type >= 0 && type < MCA_BASE_VAR_TYPE_MAX); + + /* There are data holes in the var struct */ + OPAL_DEBUG_ZERO(var); + + /* Initialize the array if it has never been initialized */ + if (!initialized) { + mca_base_var_init(); + } + + /* See if this entry is already in the array */ + var_index = var_find (project_name, framework_name, component_name, variable_name, + true); + + if (0 > var_index) { + /* Create a new parameter entry */ + group = group_register (project_name, framework_name, component_name, + NULL); + if (-1 > group) { + return group; + } + + /* Read-only and constant variables can't be settable */ + if (scope < MCA_BASE_VAR_SCOPE_LOCAL || (flags & MCA_BASE_VAR_FLAG_DEFAULT_ONLY)) { + if ((flags & MCA_BASE_VAR_FLAG_DEFAULT_ONLY) && (flags & MCA_BASE_VAR_FLAG_SETTABLE)) { + opal_show_help("help-mca-var.txt", "invalid-flag-combination", + "MCA_BASE_VAR_FLAG_DEFAULT_ONLY", "MCA_BASE_VAR_FLAG_SETTABLE"); + return OPAL_ERROR; + } + + /* Should we print a warning for other cases? */ + flags &= ~MCA_BASE_VAR_FLAG_SETTABLE; + } + + var = OBJ_NEW(mca_base_var_t); + + var->mbv_type = type; + var->mbv_flags = flags; + var->mbv_group_index = group; + var->mbv_verbosity = verbosity; + var->mbv_scope = scope; + var->mbv_synonym_for = synonym_for; + var->mbv_bind = bind; + + if (NULL != description) { + var->mbv_description = strdup(description); + } + + if (NULL != variable_name) { + var->mbv_variable_name = strdup(variable_name); + if (NULL == var->mbv_variable_name) { + OBJ_RELEASE(var); + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + + ret = mca_base_var_generate_full_name4 (NULL, framework_name, component_name, + variable_name, &var->mbv_full_name); + if (OPAL_SUCCESS != ret) { + OBJ_RELEASE(var); + return OPAL_ERROR; + } + + ret = mca_base_var_generate_full_name4 (project_name, framework_name, component_name, + variable_name, &var->mbv_long_name); + if (OPAL_SUCCESS != ret) { + OBJ_RELEASE(var); + return OPAL_ERROR; + } + + /* Add it to the array. Note that we copy the mca_var_t by value, + so the entire contents of the struct is copied. The synonym list + will always be empty at this point, so there's no need for an + extra RETAIN or RELEASE. */ + var_index = opal_pointer_array_add (&mca_base_vars, var); + if (0 > var_index) { + OBJ_RELEASE(var); + return OPAL_ERROR; + } + + if (0 <= group) { + mca_base_var_group_add_var (group, var_index); + } + + mca_base_var_count++; + } else { + ret = var_get (var_index, &var, true); + if (OPAL_SUCCESS != ret) { + /* Shouldn't event happen */ + return OPAL_ERROR; + } + + if (var->mbv_type != type) { +#if OPAL_ENABLE_DEBUG + opal_show_help("help-mca-var.txt", + "re-register-with-different-type", + true, var->mbv_full_name); +#endif + return OPAL_ERR_VALUE_OUT_OF_BOUNDS; + } + } + + if (var->mbv_enumerator) { + OBJ_RELEASE (var->mbv_enumerator); + } + + if (NULL != enumerator) { + OBJ_RETAIN(enumerator); + } + + var->mbv_enumerator = enumerator; + + if (flags & MCA_BASE_VAR_FLAG_SYNONYM) { + mca_base_var_t *original = opal_pointer_array_get_item (&mca_base_vars, synonym_for); + + opal_value_array_append_item(&original->mbv_synonyms, &var_index); + } else { + var->mbv_storage = storage; + } + + ret = var_set_initial (var); + if (OPAL_SUCCESS != ret) { + return ret; + } + + var->mbv_flags |= MCA_BASE_VAR_FLAG_VALID; + + /* All done */ + return var_index; +} + +int mca_base_var_register (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, mca_base_var_type_t type, + mca_base_var_enum_t *enumerator, int bind, + mca_base_var_flag_t flags, + mca_base_var_verbosity_t verbosity, + mca_base_var_scope_t scope, void *storage) +{ + /* Only integer variables can have enumerator */ + assert (NULL == enumerator || MCA_BASE_VAR_TYPE_INT == type); + + return register_variable (project_name, framework_name, component_name, + variable_name, description, type, enumerator, + bind, flags, verbosity, scope, -1, storage); +} + +int mca_base_component_var_register (const mca_base_component_t *component, + const char *variable_name, const char *description, + mca_base_var_type_t type, mca_base_var_enum_t *enumerator, + int bind, mca_base_var_flag_t flags, + mca_base_var_verbosity_t verbosity, + mca_base_var_scope_t scope, void *storage) +{ + /* XXX -- component_update -- We will stash the project name in the component */ + return mca_base_var_register (NULL, component->mca_type_name, + component->mca_component_name, + variable_name, description, type, enumerator, + bind, flags, verbosity, scope, storage); +} + +int mca_base_var_register_synonym (int synonym_for, const char *project_name, + const char *framework_name, + const char *component_name, + const char *synonym_name, + mca_base_var_syn_flag_t flags) +{ + mca_base_var_flag_t var_flags = MCA_BASE_VAR_FLAG_SYNONYM; + mca_base_var_t *var; + int ret; + + ret = var_get (synonym_for, &var, false); + if (OPAL_SUCCESS != ret || VAR_IS_SYNONYM(var[0])) { + return OPAL_ERR_BAD_PARAM; + } + + if (flags & MCA_BASE_VAR_SYN_FLAG_DEPRECATED) { + var_flags |= MCA_BASE_VAR_FLAG_DEPRECATED; + } + + return register_variable (project_name, framework_name, component_name, + synonym_name, NULL, var->mbv_type, var->mbv_enumerator, + var->mbv_bind, var_flags, var->mbv_verbosity, var->mbv_scope, + synonym_for, NULL); +} + +/* + * Lookup the initial value for a parameter + */ +/* + * Lookup a param in the environment + */ +static int var_set_from_env (mca_base_var_t *var) +{ + const char *var_full_name = var->mbv_full_name; + bool deprecated = VAR_IS_DEPRECATED(var[0]); + char *source, *source_env; + char *value, *value_env; + int ret; + + if (VAR_IS_SYNONYM(var[0])) { + ret = var_get (var->mbv_synonym_for, &var, false); + if (OPAL_SUCCESS != ret) { + return OPAL_ERROR; + } + + if (var->mbv_source >= MCA_BASE_VAR_SOURCE_ENV) { + return OPAL_SUCCESS; + } + } + + ret = asprintf (&source, "%sSOURCE_%s", mca_prefix, var_full_name); + if (0 > ret) { + return OPAL_ERROR; + } + + ret = asprintf (&value, "%s%s", mca_prefix, var_full_name); + if (0 > ret) { + free (source); + return OPAL_ERROR; + } + + source_env = getenv (source); + value_env = getenv (value); + + free (source); + free (value); + + if (NULL == value_env) { + return OPAL_ERR_NOT_FOUND; + } + + /* we found an environment variable but this variable is default-only. print + a warning. */ + if (VAR_IS_DEFAULT_ONLY(var[0])) { + opal_show_help("help-mca-var.txt", "default-only-param-set", + true, var_full_name); + + return OPAL_ERR_NOT_FOUND; + } + + if (MCA_BASE_VAR_SOURCE_OVERRIDE == var->mbv_source) { + if (!mca_base_var_suppress_override_warning) { + opal_show_help("help-mca-var.txt", "overridden-param-set", + true, var_full_name); + } + + return OPAL_ERR_NOT_FOUND; + } + + var->mbv_source = MCA_BASE_VAR_SOURCE_ENV; + + if (NULL != source_env) { + if (0 == strncasecmp (source_env, "file:", 5)) { + var->mbv_source_file = strdup (source_env + 5); + if (0 == strcmp (var->mbv_source_file, mca_base_var_override_file)) { + var->mbv_source = MCA_BASE_VAR_SOURCE_OVERRIDE; + } else { + var->mbv_source = MCA_BASE_VAR_SOURCE_FILE; + } + } else if (0 == strcasecmp (source_env, "command")) { + var->mbv_source = MCA_BASE_VAR_SOURCE_COMMAND_LINE; + } + } + + if (deprecated) { + switch (var->mbv_source) { + case MCA_BASE_VAR_SOURCE_ENV: + opal_show_help("help-mca-var.txt", "deprecated-mca-env", + var->mbv_full_name); + break; + case MCA_BASE_VAR_SOURCE_COMMAND_LINE: + opal_show_help("help-mca-var.txt", "deprecated-mca-cli", + var->mbv_full_name); + break; + case MCA_BASE_VAR_SOURCE_FILE: + case MCA_BASE_VAR_SOURCE_OVERRIDE: + opal_show_help("help-mca-var.txt", "deprecated-mca-file", + var->mbv_full_name, var->mbv_source_file); + break; + + case MCA_BASE_VAR_SOURCE_DEFAULT: + case MCA_BASE_VAR_SOURCE_MAX: + case MCA_BASE_VAR_SOURCE_SET: + /* silence compiler warnings about unhandled enumerations */ + break; + } + } + + return var_set_from_string (var, value_env); +} + + +/* + * Lookup a param in the files + */ +static int var_set_from_file (mca_base_var_t *var, opal_list_t *file_values) +{ + const char *var_full_name = var->mbv_full_name; + const char *var_long_name = var->mbv_long_name; + bool deprecated = VAR_IS_DEPRECATED(var[0]); + mca_base_var_file_value_t *fv; + int ret; + + if (VAR_IS_SYNONYM(var[0])) { + ret = var_get (var->mbv_synonym_for, &var, false); + if (OPAL_SUCCESS != ret) { + return OPAL_ERROR; + } + + if (var->mbv_source >= MCA_BASE_VAR_SOURCE_FILE) { + return OPAL_SUCCESS; + } + } + + /* Scan through the list of values read in from files and try to + find a match. If we do, cache it on the param (for future + lookups) and save it in the storage. */ + + OPAL_LIST_FOREACH(fv, file_values, mca_base_var_file_value_t) { + if (0 != strcmp(fv->mbvfv_var, var_full_name) && + 0 != strcmp(fv->mbvfv_var, var_long_name)) { + continue; + } + + /* found it */ + if (VAR_IS_DEFAULT_ONLY(var[0])) { + opal_show_help("help-mca-var.txt", "default-only-param-set", + true, var_full_name); + + return OPAL_ERR_NOT_FOUND; + } + + if (MCA_BASE_VAR_SOURCE_OVERRIDE == var->mbv_source) { + if (!mca_base_var_suppress_override_warning) { + opal_show_help("help-mca-var.txt", "overridden-param-set", + true, var_full_name); + } + + return OPAL_ERR_NOT_FOUND; + } + + if (deprecated) { + opal_show_help("help-mca-var.txt", "deprecated-mca-file", + var_full_name, var->mbv_source_file); + } + + if (NULL != fv->mbvfv_file) { + var->mbv_source_file = strdup (fv->mbvfv_file); + if (NULL == var->mbv_source_file) { + return OPAL_ERR_OUT_OF_RESOURCE; + } + } + + var->mbv_source = MCA_BASE_VAR_SOURCE_FILE; + + return var_set_from_string (var, fv->mbvfv_value); + } + + return OPAL_ERR_NOT_FOUND; +} + +static int var_set_initial (mca_base_var_t *var) +{ + int ret; + + var->mbv_source = MCA_BASE_VAR_SOURCE_DEFAULT; + + /* Check all the places that the param may be hiding, in priority + order. If the default only flag is set the user will get a + warning if they try to set a value from the environment or a + file. */ + ret = var_set_from_file (var, &mca_base_var_override_values); + if (OPAL_SUCCESS == ret) { + var->mbv_flags = ~MCA_BASE_VAR_FLAG_SETTABLE & (var->mbv_flags | MCA_BASE_VAR_FLAG_OVERRIDE); + var->mbv_source = MCA_BASE_VAR_SOURCE_OVERRIDE; + } + + ret = var_set_from_env (var); + if (OPAL_ERR_NOT_FOUND != ret) { + return ret; + } + + ret = var_set_from_file (var, &mca_base_var_file_values); + if (OPAL_ERR_NOT_FOUND != ret) { + return ret; + } + + return OPAL_SUCCESS; +} + +/* + * Create an empty param container + */ +static void var_constructor(mca_base_var_t *var) +{ + memset ((char *) var + sizeof (var->super), 0, sizeof (*var) - sizeof (var->super)); + + var->mbv_type = MCA_BASE_VAR_TYPE_MAX; + OBJ_CONSTRUCT(&var->mbv_synonyms, opal_value_array_t); + opal_value_array_init (&var->mbv_synonyms, sizeof (int)); +} + + +/* + * Free all the contents of a param container + */ +static void var_destructor(mca_base_var_t *var) +{ + if (NULL != var->mbv_variable_name) { + free(var->mbv_variable_name); + } + if (NULL != var->mbv_full_name) { + free(var->mbv_full_name); + } + if (NULL != var->mbv_description) { + free(var->mbv_description); + } + if (MCA_BASE_VAR_TYPE_STRING == var->mbv_type && + NULL != var->mbv_storage) { + free (var->mbv_storage->stringval); + } + if (NULL != var->mbv_source_file) { + free (var->mbv_source_file); + } + + if (NULL != var->mbv_enumerator) { + OBJ_RELEASE(var->mbv_enumerator); + } + + /* Destroy the synonym array */ + OBJ_DESTRUCT(&var->mbv_synonyms); + + /* mark this parameter as invalid */ + var->mbv_type = MCA_BASE_VAR_TYPE_MAX; + +#if OPAL_ENABLE_DEBUG + /* Cheap trick to reset everything to NULL */ + var_constructor(var); +#endif +} + + +static void fv_constructor(mca_base_var_file_value_t *f) +{ + memset ((char *) f + sizeof (f->super), 0, sizeof (*f) - sizeof (f->super)); +} + + +static void fv_destructor(mca_base_var_file_value_t *f) +{ + if (NULL != f->mbvfv_var) { + free(f->mbvfv_var); + } + if (NULL != f->mbvfv_value) { + free(f->mbvfv_value); + } + if (NULL != f->mbvfv_file) { + free(f->mbvfv_file); + } + fv_constructor(f); +} + +static void mca_base_var_group_constructor (mca_base_var_group_t *group) +{ + memset ((char *) group + sizeof (group->super), 0, sizeof (*group) - sizeof (group->super)); + + OBJ_CONSTRUCT(&group->group_subgroups, opal_value_array_t); + opal_value_array_init (&group->group_subgroups, sizeof (int)); + + OBJ_CONSTRUCT(&group->group_vars, opal_value_array_t); + opal_value_array_init (&group->group_vars, sizeof (int)); +} + +static void mca_base_var_group_destructor (mca_base_var_group_t *group) +{ + free (group->group_full_name); + group->group_full_name = NULL; + + free (group->group_description); + group->group_description = NULL; + + free (group->group_project); + group->group_project = NULL; + + free (group->group_framework); + group->group_framework = NULL; + + free (group->group_component); + group->group_component = NULL; + + OBJ_DESTRUCT(&group->group_subgroups); + OBJ_DESTRUCT(&group->group_vars); +} + +static char *source_name(mca_base_var_t *var) +{ + char *ret; + int rc; + + switch (var->mbv_source) { + case MCA_BASE_VAR_SOURCE_DEFAULT: + return strdup ("default value"); + case MCA_BASE_VAR_SOURCE_COMMAND_LINE: + return strdup ("command line"); + case MCA_BASE_VAR_SOURCE_ENV: + return strdup ("environment variable"); + case MCA_BASE_VAR_SOURCE_FILE: + rc = asprintf(&ret, "file (%s)", var->mbv_source_file); + /* some compilers will warn if the return code of asprintf is not checked (even if it is cast to void) */ + if (0 > rc) { + return NULL; + } + return ret; + case MCA_BASE_VAR_SOURCE_OVERRIDE: + return strdup ("override file"); + case MCA_BASE_VAR_SOURCE_SET: + return strdup ("code"); + case MCA_BASE_VAR_SOURCE_MAX: + break; + /* don't define a default so we get a warning if for unhandled enum variables */ + } + + return strdup ("unknown (!)"); +} + +int mca_base_var_check_exclusive (const char *project, + const char *type_a, + const char *component_a, + const char *param_a, + const char *type_b, + const char *component_b, + const char *param_b) +{ + mca_base_var_t *var_a, *var_b; + int var_ai, var_bi; + + var_ai = mca_base_var_find (project, type_a, component_a, param_a); + if (var_ai < 0) { + return OPAL_ERR_NOT_FOUND; + } + + var_bi = mca_base_var_find (project, type_b, component_b, param_b); + if (var_bi < 0) { + return OPAL_ERR_NOT_FOUND; + } + + (void) var_get (var_ai, &var_a, true); + (void) var_get (var_bi, &var_b, true); + + if (MCA_BASE_VAR_SOURCE_DEFAULT != var_a->mbv_source && + MCA_BASE_VAR_SOURCE_DEFAULT != var_b->mbv_source) { + char *str_a, *str_b; + + /* Form cosmetic string names for A */ + str_a = source_name(var_a); + + /* Form cosmetic string names for B */ + str_b = source_name(var_b); + + /* Print it all out */ + opal_show_help("help-mca-var.txt", + "mutually-exclusive-vars", + true, var_a->mbv_full_name, + str_a, var_b->mbv_full_name, + str_b); + + /* Free the temp strings */ + free(str_a); + free(str_b); + + return OPAL_ERR_BAD_PARAM; + } + + return OPAL_SUCCESS; +} + +int mca_base_var_get_count (void) +{ + return mca_base_var_count; +} + +int mca_base_var_group_get_count (void) +{ + return mca_base_var_group_count; +} + +int mca_base_var_group_get_stamp (void) +{ + return mca_base_var_groups_timestamp; +} Index: opal/mca/base/mca_base_var.h =================================================================== --- opal/mca/base/mca_base_var.h (revision 0) +++ opal/mca/base/mca_base_var.h (working copy) @@ -0,0 +1,794 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2008-2011 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2013 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file + * This file presents the MCA variable interface. + * + * Note that there are two scopes for MCA variables: "normal" and + * attributes. Specifically, all MCA variables are "normal" -- some + * are special and may also be found on attributes on communicators, + * datatypes, or windows. + * + * In general, these functions are intended to be used as follows: + * + * - Creating MCA variables + * -# Register a variable, get an index back + * - Using MCA variables + * -# Lookup a "normal" variable value on a specific index, or + * -# Lookup an attribute variable on a specific index and + * communicator / datatype / window. + * + * MCA variables can be defined in multiple different places. As + * such, variables are \em resolved to find their value. The order + * of resolution is as follows: + * + * - An "override" location that is only available to be set via the + * mca_base_param API. + * - Look for an environment variable corresponding to the MCA + * variable. + * - See if a file contains the MCA variable (MCA variable files are + * read only once -- when the first time any mca_param_t function is + * invoked). + * - If nothing else was found, use the variable's default value. + * + * Note that there is a second header file (mca_base_vari.h) + * that contains several internal type delcarations for the variable + * system. The internal file is only used within the variable system + * itself; it should not be required by any other Open MPI entities. + */ + +#ifndef OPAL_MCA_BASE_VAR_H +#define OPAL_MCA_BASE_VAR_H + +#include "opal_config.h" + +#include "opal/class/opal_list.h" +#include "opal/mca/mca.h" + +/** + * The types of MCA variables. + */ +typedef enum { + /** The variable is of type integer. */ + MCA_BASE_VAR_TYPE_INT, + /** The variable is of type string. */ + MCA_BASE_VAR_TYPE_STRING, + /** The variable is of type bool */ + MCA_BASE_VAR_TYPE_BOOL, + /** Maximum variable type. */ + MCA_BASE_VAR_TYPE_MAX +} mca_base_var_type_t; + + +/** + * Source of an MCA variable's value + */ +typedef enum { + /** The default value */ + MCA_BASE_VAR_SOURCE_DEFAULT, + /** The value came from the command line */ + MCA_BASE_VAR_SOURCE_COMMAND_LINE, + /** The value came from the environment */ + MCA_BASE_VAR_SOURCE_ENV, + /** The value came from a file */ + MCA_BASE_VAR_SOURCE_FILE, + /** The value came a "set" API call */ + MCA_BASE_VAR_SOURCE_SET, + /** The value came from the override file */ + MCA_BASE_VAR_SOURCE_OVERRIDE, + + /** Maximum source type */ + MCA_BASE_VAR_SOURCE_MAX +} mca_base_var_source_t; + +/** + * MCA variable scopes + * + * Equivalent to MPIT scopes + */ +typedef enum { + /** The value of this variable will not change after it + is registered. Implies !MCA_BASE_VAR_FLAG_SETTABLE */ + MCA_BASE_VAR_SCOPE_CONSTANT, + /** The value of this variable may change but it should not be + changed using the mca_base_var_set function. Implies + !MCA_BASE_VAR_FLAG_SETTABLE */ + MCA_BASE_VAR_SCOPE_READONLY, + /** The value of this variable may be changed locally. */ + MCA_BASE_VAR_SCOPE_LOCAL, + /** The value of this variable must be set to a consistent value + within a group */ + MCA_BASE_VAR_SCOPE_GROUP, + /** The value of this variable must be set to the same value + within a group */ + MCA_BASE_VAR_SCOPE_GROUP_EQ, + /** The value of this variable must be set to a consistent value + for all processes */ + MCA_BASE_VAR_SCOPE_ALL, + /** The value of this variable must be set to the same value + for all processes */ + MCA_BASE_VAR_SCOPE_ALL_EQ, + MCA_BASE_VAR_SCOPE_MAX +} mca_base_var_scope_t; + +typedef enum { + MCA_BASE_VAR_VERBOSITY_USER_BASIC, + MCA_BASE_VAR_VERBOSITY_USER_DETAIL, + MCA_BASE_VAR_VERBOSITY_USER_ALL, + MCA_BASE_VAR_VERBOSITY_TUNER_BASIC, + MCA_BASE_VAR_VERBOSITY_TUNER_DETAIL, + MCA_BASE_VAR_VERBOSITY_TUNER_ALL, + MCA_BASE_VAR_VERBOSITY_MPIDEV_BASIC, + MCA_BASE_VAR_VERBOSITY_MPIDEV_DETAIL, + MCA_BASE_VAR_VERBOSITY_MPIDEV_ALL, + MCA_BASE_VAR_VERBOSITY_MAX +} mca_base_var_verbosity_t; + +typedef enum { + MCA_BASE_VAR_SYN_FLAG_DEPRECATED = 0x0001 +} mca_base_var_syn_flag_t; + +typedef enum { + /** Variable is internal (hidden from *_info/MPIT) */ + MCA_BASE_VAR_FLAG_INTERNAL = 0x0001, + /** Variable will always be the default value. Implies + !MCA_BASE_VAR_FLAG_SETTABLE */ + MCA_BASE_VAR_FLAG_DEFAULT_ONLY = 0x0002, + /** Variable can be set with mca_base_var_set() */ + MCA_BASE_VAR_FLAG_SETTABLE = 0x0004, + /** Variable is deprecated */ + MCA_BASE_VAR_FLAG_DEPRECATED = 0x0008, + /** Variable has been overridden */ + MCA_BASE_VAR_FLAG_OVERRIDE = 0x0010 +} mca_base_var_flag_t; + +struct mca_base_var_enum_value_t { + const int value; + const char *string; +}; + +typedef struct mca_base_var_enum_value_t mca_base_var_enum_value_t; + +struct mca_base_var_enum_t { + opal_object_t super; + + char *enum_name; + + mca_base_var_enum_value_t *enum_values; +}; + +typedef struct mca_base_var_enum_t mca_base_var_enum_t; + +/** + * Types for MCA parameters. + */ +typedef union { + /** Integer value */ + int intval; + /** String value */ + char *stringval; + /** Boolean value */ + bool boolval; +} mca_base_var_storage_t; + + +/** + * Entry for holding information about an MCA variable. + */ +struct mca_base_var_t { + /** Allow this to be an OPAL OBJ */ + opal_object_t super; + + /** Variable index. This will remain constant until mca_base_var_finalize() + is called. */ + int mbv_index; + /** Group index. This will remain constant until mca_base_var_finalize() + is called. This variable will be deregistered if the associated group + is deregistered with mca_base_var_group_deregister() */ + int mbv_group_index; + + /** Verbosity level of this variable */ + mca_base_var_verbosity_t mbv_verbosity; + + /** Enum indicating the type of the variable (integer, string, boolean) */ + mca_base_var_type_t mbv_type; + + /** String of the variable name */ + char *mbv_variable_name; + /** Full variable name, in case it is not __ */ + char *mbv_full_name; + /** Long variable name ___ */ + char *mbv_long_name; + + /** List of synonym names for this variable. This *must* be a + pointer (vs. a plain opal_list_t) because we copy this whole + struct into a new var for permanent storage + (opal_vale_array_append_item()), and the internal pointers in + the opal_list_t will be invalid when that happens. Hence, we + simply keep a pointer to an external opal_list_t. Synonyms + are uncommon enough that this is not a big performance hit. */ + opal_value_array_t mbv_synonyms; + + /** Variable flags */ + mca_base_var_flag_t mbv_flags; + + /** Variable scope */ + mca_base_var_scope_t mbv_scope; + + /** Source of the current value */ + mca_base_var_source_t mbv_source; + + /** Synonym for */ + int mbv_synonym_for; + + /** Variable description */ + char *mbv_description; + + /** File the value came from */ + char *mbv_source_file; + + /** Value enumerator (only valid for integer variables) */ + mca_base_var_enum_t *mbv_enumerator; + + /** Bind value for this variable (0 - none) */ + int mbv_bind; + + /** Storage for this variable */ + mca_base_var_storage_t *mbv_storage; +}; +/** + * Convenience typedef. + */ +typedef struct mca_base_var_t mca_base_var_t; + +struct mca_base_var_group_t { + opal_list_item_t super; + + /** Index of group */ + int group_index; + + /** Group is valid (registered) */ + bool group_isvalid; + + /** Group name */ + char *group_full_name; + + char *group_project; + char *group_framework; + char *group_component; + + /** Group help message (description) */ + char *group_description; + + /** Integer value array of subgroup indices */ + opal_value_array_t group_subgroups; + + /** Integer array of group variables */ + opal_value_array_t group_vars; +}; + +typedef struct mca_base_var_group_t mca_base_var_group_t; + +/* + * Global functions for MCA + */ + +BEGIN_C_DECLS + +/** + * Object declarayion for mca_base_var_t + */ +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_t); + + +/** + * Object declaration for mca_base_var_group_t + */ +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_group_t); + +/** + * Object declaration for mca_base_var_enum_t + */ +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_enum_t); + +/** + * Initialize the MCA variable system. + * + * @retval OPAL_SUCCESS + * + * This function initalizes the MCA variable system. It is + * invoked internally (by mca_base_open()) and is only documented + * here for completeness. + */ +OPAL_DECLSPEC int mca_base_var_init(void); + +/** + * Register an MCA variable group + * + * @param[in] project_name Project name for this group. + * @param[in] framework_name Framework name for this group. + * @param[in] component_name Component name for this group. + * @param[in] descrition Description of this group. + * + * @retval index Unique group index + * @return opal error code on Error + * + * Create an MCA variable group. If the group already exists + * this call is equivalent to mca_base_ver_find_group(). + */ +OPAL_DECLSPEC int mca_base_var_group_register(const char *project_name, + const char *framework_name, + const char *component_name, + const char *description); + +/** + * Register an MCA variable group for a component + * + * @param[in] component [in] Pointer to the component for which the + * group is being registered. + * @param[in] description Description of this group. + * + * @retval index Unique group index + * @return opal error code on Error + */ +OPAL_DECLSPEC int mca_base_var_group_component_register (const mca_base_component_t *component, + const char *description); + +/** + * Deregister an MCA param group + * + * @param group_index [in] Group index from mca_base_var_group_register (), + * mca_base_var_group_find(). + * + * This call deregisters all associated variables and subgroups. + */ +OPAL_DECLSPEC int mca_base_var_group_deregister (int group_index); + +/** + * Find an MCA group + * + * @param project_name [in] Project name + * @param framework_name [in] Type name + * @param component_name [in] Component name + */ +OPAL_DECLSPEC int mca_base_var_group_find (const char *project_name, + const char *framework_name, + const char *component_name); + +/** + * Dump info from a group + * + * @param[in] group_index Group index + * @param[out] group Storage for the group object pointer. + * + * @retval OPAL_ERR_NOT_FOUND If the group specified by group_index does not exist. + * @retval OPAL_ERR_OUT_OF_RESOURCE If memory allocation fails. + * @retval OPAL_SUCCESS If the group is dumped successfully. + * + * The returned pointer belongs to the MCA variable system. Do not modify/release/retain + * the pointer. + */ +OPAL_DECLSPEC int mca_base_var_group_get (const int group_index, + const mca_base_var_group_t **group); + +/** + * Set/unset a flags for all variables in a group. + * + * @param[in] group_index Index of group + * @param[in] flag Flag(s) to set or unset. + * @param[in] set Boolean indicating whether to set flag(s). + * + * Set a flag for every variable in a group. See mca_base_var_set_flag() for more info. + */ +OPAL_DECLSPEC int mca_base_var_group_set_var_flag (const int group_index, + mca_base_var_flag_t flags, + bool set); + +/** + * Get the number of registered MCA groups + * + * @retval count Number of registered MCA groups + */ +OPAL_DECLSPEC int mca_base_var_group_get_count (void); + +/** + * Get a relative timestamp for the MCA group system + * + * @retval stamp + * + * This value will change if groups or variables are either added or removed. + */ +OPAL_DECLSPEC int mca_base_var_group_get_stamp (void); + +/** + * Register an MCA variable + * + * @param[in] project_name The name of the project associated with + * this variable. + * @param[in] framework_name The name of the framework associated with + * this variable. + * @param[in] component_name The name of the component associated with + * this variable. + * @param[in] variable_name The name of this variable. + * @param[in] description A string describing the use and valid + * values of the variable (string). + * @param[in] type The type of this variable (string, int, bool). + * @param[in] enumerator Enumerator describing valid values. + * @param[in] bind Hint for MPIT to specify type of binding (0 = none) + * @param[in] flags Flags for this variable. + * @param[in] verbosity Verbosity level for this variable. + * @param[in] scope Indicates the scope of this variable. + * @param[in,out] storage Pointer to the value's location. + * + * @retval index Index value representing this variable. + * @retval OPAL_ERR_OUT_OF_RESOURCE Upon failure to allocate memory. + * @retval OPAL_ERROR Upon failure to register the variable. + * + * This function registers an MCA variable and associates it + * with a specific group. + * + * The {description} is a string of arbitrary length (verbose is + * good!) for explaining what the variable is for and what its + * valid values are. This message is used in help messages, such + * as the output from the ompi_info executable. + * + * The {enumerator} describes the valid values of an integer + * variable. The variable may be set to either the enumerator value + * (0, 1, 2, etc) or a string representing that value. The + * value provided by the user will be compared against the + * values in the enumerator. The {enumerator} is not valid with + * any other type of variable. {enumerator} is retained until + * either the variable is deregistered using mca_base_var_deregister(), + * mca_base_var_group_deregister(), or mca_base_var_finalize(). + * + * The {flags} indicate attributes of this variable (internal, + * settable, default only, etc). + * + * If MCA_BASE_VAR_FLAG_SETTABLE is set in {flags}, this variable + * may be set using mca_base_var_set_value(). + * + * If MCA_BASE_VAR_FLAG_INTERNAL is set in {flags}, this variable + * is not shown by default in the output of ompi_info. That is, + * this variable is considered internal to the Open MPI implementation + * and is not supposed to be viewed / changed by the user. + * + * If MCA_BASE_VAR_FLAG_DEFAULT_ONLY is set in {flags}, then the + * value provided in storage will not be modified by the MCA + * variable system. It is up to the caller to specify (using the scope) + * if this value may change (MCA_BASE_VAR_SCOPE_READONLY) + * or remain constant (MCA_BASE_VAR_SCOPE_CONSTANT). + * MCA_BASE_VAR_FLAG_DEFAULT_ONLY must not be specified with + * MCA_BASE_VAR_FLAG_SETTABLE. + * + * Set MCA_BASE_VAR_FLAG_DEPRECATED in {flags} to indicate that + * this variable name is deprecated. The user will get a warning + * if they set this variable. + * + * The {scope} is for informational purposes to indicate how this + * variable should be set or if it is considered constant or readonly. + * A readonly scope means something different than setting {read_only} + * to true. A readonly scope will still allow the variable to be + * overridden by a file or environment variable. + * + * The {value} indicates where the value can be found. It may be set + * if MCA_BASE_VAR_FLAG_DEFAULT_ONLY and MCA_BASE_VAR_FLAG_SETTABLE + * are set. If the variable is a string it should be allocated on + * the heap and the MCA variable system will ensure the value is + * freed when mca_base_var_finalize() is called. + */ +OPAL_DECLSPEC int mca_base_var_register (const char *project_name, const char *framework_name, + const char *component_name, const char *variable_name, + const char *description, mca_base_var_type_t type, + mca_base_var_enum_t *enumerator, int bind, mca_base_var_flag_t flags, + mca_base_var_verbosity_t verbosity, + mca_base_var_scope_t scope, void *storage); + +/** + * Convinience function for registering a variable associated with a component. + * See mca_base_var_register(). + */ +OPAL_DECLSPEC int mca_base_component_var_register (const mca_base_component_t *component, + const char *variable_name, const char *description, + mca_base_var_type_t type, mca_base_var_enum_t *enumerator, + int bind, mca_base_var_flag_t flags, + mca_base_var_verbosity_t verbosity, + mca_base_var_scope_t scope, void *storage); + +/** + * Register a synonym name for an MCA variable. + * + * @param[in] synonym_for The index of the original variable. This index + * must not refer to a synonym. + * @param[in] project_name The project this synonym belongs to. Should + * not be NULL (except for legacy reasons). + * @param[in] framework_name The framework this synonym belongs to. + * @param[in] component_name The component this synonym belongs to. + * @param[in] synonym_name The synonym name. + * @param[in] flags Flags for this synonym. + * + * @returns index Variable index for new synonym on success. + * @returns OPAL_ERR_BAD_VAR If synonym_for does not reference a valid + * variable. + * @returns OPAL_ERR_OUT_OF_RESOURCE If memory could not be allocated. + * @returns OPAL_ERROR For all other errors. + * + * Upon success, this function creates a synonym MCA variable + * that will be treated almost exactly like the original. The + * type (int or string) is irrelevant; this function simply + * creates a new name that by which the same variable value is + * accessible. + * + * Note that the original variable name has precendence over all + * synonyms. For example, consider the case if variable is + * originally registered under the name "A" and is later + * registered with synonyms "B" and "C". If the user sets values + * for both MCA variable names "A" and "B", the value associated + * with the "A" name will be used and the value associated with + * the "B" will be ignored (and will not even be visible by the + * mca_base_var_*() API). If the user sets values for both MCA + * variable names "B" and "C" (and does *not* set a value for + * "A"), it is undefined as to which value will be used. + */ +OPAL_DECLSPEC int mca_base_var_register_synonym (int synonym_for, const char *project_name, + const char *framework_name, + const char *component_name, + const char *synonym_name, + mca_base_var_syn_flag_t flags); + +/** + * Deregister a MCA variable or synonym + * + * @param index Index returned from mca_base_var_register() or + * mca_base_var_register_synonym(). + * + * Deregistering a variable does not free the index or any memory assoicated + * with the variable. All memory will be freed and the index released when + * mca_base_var_finalize() is called. + * + * If an enumerator is associated with this variable it will be dereferenced. + */ +OPAL_DECLSPEC int mca_base_var_deregister(int index); + + +/** + * Get the current value of an MCA variable. + * + * @param[in] index Index of variable + * @param[in,out] value Pointer to copy the value to. Can be NULL. + * @param[in,out] value_size Size of memory pointed to by value. + * copied size will be returned in value_size. + * @param[out] source Source of current value. Can be NULL. + * @param[out] source_file Source file for the current value if + * it was set from a file. + * + * @return OPAL_ERROR Upon failure. The contents of value are + * undefined. + * @return OPAL_SUCCESS Upon success. value (if not NULL) will be filled + * with the variable's current value. value_size will contain the size + * copied. source (if not NULL) will contain the source of the variable. + * + * Note: The value can be changed by the registering code without using + * the mca_base_var_* interface so the source may be incorrect. + */ +OPAL_DECLSPEC int mca_base_var_get_value (int index, const void *value, + mca_base_var_source_t *source, + const char **source_file); + +/** + * Sets an "override" value for an integer MCA variable. + * + * @param[in] index Index of MCA variable to set + * @param[in] value Pointer to the value to set. Should point to + * a char * for string variables or a int * for integer variables. + * @param[in] size Size of value. + * @param[in] source Source of this value. + * @param[in] source_file Source file if source is MCA_BASE_VAR_SOURCE_FILE. + * + * @retval OPAL_SUCCESS Upon success. + * @retval OPAL_ERR_PERM If the variable is not settable. + * @retval OPAL_ERR_BAD_PARAM If the variable does not exist or has + * been deregistered. + * @retval OPAL_ERROR On other error. + * + * This function sets the value of an MCA variable. This value will + * overwrite the current value of the variable (or if index represents + * a synonym the variable the synonym represents) if the value is + * settable. + */ +OPAL_DECLSPEC int mca_base_var_set_value (int index, void *value, size_t size, + mca_base_var_source_t source, + const char *source_file); + +/** + * Get the string name corresponding to the MCA variable + * value in the environment. + * + * @param param_name Name of the type containing the variable. + * + * @retval string A string suitable for setenv() or appending to + * an environ-style string array. + * @retval NULL Upon failure. + * + * The string that is returned is owned by the caller; if + * appropriate, it must be eventually freed by the caller. + */ +OPAL_DECLSPEC int mca_base_var_env_name(const char *param_name, + char **env_name); + +/** + * Find the index for an MCA variable based on its names. + * + * @param type Name of the type containing the variable. + * @param component Name of the component containing the variable. + * @param param Name of the variable. + * + * @retval OPAL_ERROR If the variable was not found. + * @retval index If the variable was found. + * + * It is not always convenient to widely propagate a variable's index + * value, or it may be necessary to look up the variable from a + * different component -- where it is not possible to have the return + * value from mca_base_var_reg_int() or mca_base_var_reg_string(). + * This function can be used to look up the index of any registered + * variable. The returned index can be used with + * mca_base_var_lookup_int() and mca_base_var_lookup_string(). + */ +OPAL_DECLSPEC int mca_base_var_find (const char *project_name, + const char *type_name, + const char *component_name, + const char *param_name); + +/** + * Check that two MCA variables were not both set to non-default + * values. + * + * @param type_a [in] Framework name of variable A (string). + * @param component_a [in] Component name of variable A (string). + * @param param_a [in] Variable name of variable A (string. + * @param type_b [in] Framework name of variable A (string). + * @param component_b [in] Component name of variable A (string). + * @param param_b [in] Variable name of variable A (string. + * + * This function is useful for checking that the user did not set both + * of 2 mutually-exclusive MCA variables. + * + * This function will print an opal_show_help() message and return + * OPAL_ERR_BAD_VAR if it finds that the two variables both have + * value sources that are not MCA_BASE_VAR_SOURCE_DEFAULT. This + * means that both variables have been set by the user (i.e., they're + * not default values). + * + * Note that opal_show_help() allows itself to be hooked, so if this + * happens after the aggregated orte_show_help() system is + * initialized, the messages will be aggregated (w00t). + * + * @returns OPAL_ERR_BAD_VAR if the two variables have sources that + * are not MCA_BASE_VAR_SOURCE_DEFAULT. + * @returns OPAL_SUCCESS otherwise. + */ +OPAL_DECLSPEC int mca_base_var_check_exclusive (const char *project, + const char *type_a, + const char *component_a, + const char *param_a, + const char *type_b, + const char *component_b, + const char *param_b); + +/** + * Set or unset a flag on a variable. + * + * @param[in] index Index of variable + * @param[in] flag Flag(s) to set or unset. + * @param[in] set Boolean indicating whether to set flag(s). + * + * @returns OPAL_SUCCESS If the flags are set successfully. + * @returns OPAL_ERR_BAD_PARAM If the variable is not registered. + * @returns OPAL_ERROR Otherwise + */ +OPAL_DECLSPEC int mca_base_var_set_flag(int index, mca_base_var_flag_t flag, + bool set); + +/** + * Obtain basic info on a single variable (name, help message, etc) + * + * @param[in] index Valid variable index. + * @param[out] var Storage for the variable pointer. + * + * @retval OPAL_SUCCESS Upon success. + * @retval opal error code Upon failure. + * + * The returned pointer belongs to the MCA variable system. Do not + * modify/free/retain the pointer. + */ +OPAL_DECLSPEC int mca_base_var_get (int index, const mca_base_var_t **var); + +/** + * Obtain the number of variables that have been registered. + * + * @retval count on success + * @return opal error code on error + * + * Note: This function does not return the number of valid MCA variables as + * mca_base_var_deregister() has no impact on the variable count. The count + * returned is equal to the number of calls to mca_base_var_register with + * unique names. ie. two calls with the same name will not affect the count. + */ +OPAL_DECLSPEC int mca_base_var_get_count (void); + +/** + * Obtain a list of enironment variables describing the all + * valid (non-default) MCA variables and their sources. + * + * @param[out] env A pointer to an argv-style array of key=value + * strings, suitable for use in an environment + * @param[out] num_env A pointer to an int, containing the length + * of the env array (not including the final NULL entry). + * @param[in] internal Whether to include internal variables. + * + * @retval OPAL_SUCCESS Upon success. + * @retval OPAL_ERROR Upon failure. + * + * This function is similar to mca_base_var_dump() except that + * its output is in terms of an argv-style array of key=value + * strings, suitable for using in an environment. + */ +OPAL_DECLSPEC int mca_base_var_build_env(char ***env, int *num_env, + bool internal); + +/** + * Shut down the MCA variable system (normally only invoked by the + * MCA framework itself). + * + * @returns OPAL_SUCCESS This function never fails. + * + * This function shuts down the MCA variable repository and frees all + * associated memory. No other mca_base_var*() functions can be + * invoked after this function. + * + * This function is normally only invoked by the MCA framework itself + * when the process is shutting down (e.g., during MPI_FINALIZE). It + * is only documented here for completeness. + */ +OPAL_DECLSPEC int mca_base_var_finalize(void); + +/** + * Create a new enumerator + * + * @param[in] name Name for this enumerator + * @param[in] values List of values terminated with a NULL .string + * member. + * @param[out] enumerator Newly created enumerator. + * + * @retval OPAL_SUCCESS On success + * @retval opal error code On error + * + * This function creates a value enumerator for integer variables. The + * value array is stored by reference in the enumerator so it should not + * be allocated on the stack. The returned enumerator should be released with + * OBJ_RELEASE. + */ +OPAL_DECLSPEC int mca_base_var_enum_create (char *name, mca_base_var_enum_value_t values[], + mca_base_var_enum_t **enumerator); + +END_C_DECLS + +#endif /* OPAL_MCA_BASE_VAR_H */ Index: opal/mca/base/mca_base_vari.h =================================================================== --- opal/mca/base/mca_base_vari.h (revision 0) +++ opal/mca/base/mca_base_vari.h (working copy) @@ -0,0 +1,106 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012 Los Alamos National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** + * @file + * + * This is the private declarations for the MCA parameter system. + * This file is internal to the MCA parameter system and should not + * need to be used by any other elements in Open MPI except the + * special case of the ompi_info command. + * + * All the rest of the doxygen documentation in this file is marked as + * "internal" and won't show up unless you specifically tell doxygen + * to generate internal documentation (by default, it is skipped). + */ + +#ifndef OPAL_MCA_BASE_VAR_INTERNAL_H +#define OPAL_MCA_BASE_VAR_INTERNAL_H + +#include "opal_config.h" + +#include "opal/class/opal_object.h" +#include "opal/class/opal_list.h" +#include "opal/class/opal_value_array.h" +#include "opal/mca/base/mca_base_var.h" + +BEGIN_C_DECLS + +/* Internal flags start at bit 16 */ +#define MCA_BASE_VAR_FLAG_EXTERNAL_MASK 0x0000ffff + +typedef enum { + /** Variable is valid */ + MCA_BASE_VAR_FLAG_VALID = 0x00010000, + /** Variable is a synonym */ + MCA_BASE_VAR_FLAG_SYNONYM = 0x00020000 +} mca_base_var_flag_internal_t; + +#define VAR_FLAG_ISSET(var, flag) (!!((var).mbp_flags & (flag))) + +#define VAR_IS_VALID(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_VALID)) +#define VAR_IS_SYNONYM(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_SYNONYM)) +#define VAR_IS_INTERNAL(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL)) +#define VAR_IS_DEFAULT_ONLY(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_DEFAULT_ONLY)) +#define VAR_IS_SETTABLE(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_SETTABLE)) +#define VAR_IS_DEPRECATED(var) (!!((var).mbv_flags & MCA_BASE_VAR_FLAG_DEPRECATED)) + + +/** + * \internal + * + * Structure for holding param names and values read in from files. + */ +struct mca_base_var_file_value_t { + /** Allow this to be an OPAL OBJ */ + opal_list_item_t super; + + /** Parameter name */ + char *mbvfv_var; + /** Parameter value */ + char *mbvfv_value; + /** File it came from */ + char *mbvfv_file; +}; +/** + * \internal + * + * Convenience typedef + */ +typedef struct mca_base_var_file_value_t mca_base_var_file_value_t; + +/** + * Object declaration for mca_base_var_file_value_t + */ +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(mca_base_var_file_value_t); + + +/** + * \internal + * + * Parse a parameter file. + */ +OPAL_DECLSPEC int mca_base_parse_paramfile(const char *paramfile, opal_list_t *list); + +END_C_DECLS + +#endif /* OPAL_MCA_BASE_VAR_INTERNAL_H */