49be4b1e45
Lenny and I went back and forth on whether we should simply register another "mpi_paffinity_alone" MCA param and then try to figure out which one was set in ompi_mpi_init, but there was difficulty in figuring out what to do. So it seemed like the Right Thing to do was to implement what was committed in r18770; then we could tell where MCA parameters were set from and you could do Better Things (this is also useful in the openib BTL, where parameters can be set either via MCA parameter or via an INI file). But after that was done, it seemed only a few steps further to actually implement two new features in the MCA params area: * Synonyms (where one MCA param name is a synonym for another) * Allow MCA params and/or their synonyms to be marked as "deprecated" (printing out warnings if they are used) These features have actually long been discussed/desired, and I had some time in airports and airplanes recently where I could work in this stuff on a standalone laptop. So I did it. :-) This commit introduces these two new features, and then uses them to register mpi_paffinity_alone as a non-deprecated synonym for opal_paffinity_alone. A few other random points in this commit: * Add a few error checks for conditions that were not checked before * Correct some comments in mca_base_params.h * Add a few comments in strategic places * ompi_info now prints additional information: * for any MCA parameter that has synonyms, it lists all the synonyms * synonyms are also output as 1st-class MCA params, but with an additional attribute indicating that they have a "parent" * all MCA param name (both "real" or "synonym") will output an attribute indicating whether it is deprecated or not. A synonym is deprecated if it iself is marked as deprecated (via the mca_base_param_regist_syn() or mca_base_param_register_syn_name() functions) or if its "parent" MCA parameter is deprecated This commit was SVN r18859. The following SVN revision numbers were found above: r18770 --> open-mpi/ompi@8efe67e08c The following Trac tickets were found above: Ticket 1383 --> https://svn.open-mpi.org/trac/ompi/ticket/1383
2297 строки
72 KiB
C
2297 строки
72 KiB
C
/*
|
|
* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
|
|
* University Research and Technology
|
|
* Corporation. All rights reserved.
|
|
* Copyright (c) 2004-2008 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$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#include "opal_config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_PARAM_H
|
|
#include <sys/param.h>
|
|
#endif
|
|
|
|
#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/util/show_help.h"
|
|
#include "opal/class/opal_hash_table.h"
|
|
#if 0
|
|
/* JMS commented out for now -- see lookup_keyvals() below for an
|
|
explanation */
|
|
#include "ompi/attribute/attribute.h"
|
|
#endif
|
|
#include "opal/util/printf.h"
|
|
#include "opal/util/argv.h"
|
|
#include "opal/mca/mca.h"
|
|
#include "opal/mca/base/mca_base_param.h"
|
|
#include "opal/mca/base/mca_base_param_internal.h"
|
|
#include "opal/constants.h"
|
|
#include "opal/util/output.h"
|
|
#include "opal/util/opal_environ.h"
|
|
|
|
/*
|
|
* Local types
|
|
*/
|
|
|
|
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_key);
|
|
#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,
|
|
opal_hash_table_t *attrs,
|
|
mca_base_param_source_t *source);
|
|
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_keyvals(mca_base_param_t *param,
|
|
mca_base_param_storage_t *storage,
|
|
opal_hash_table_t *attrs);
|
|
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);
|
|
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);
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
if (!initialized) {
|
|
|
|
/* 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));
|
|
|
|
/* 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);
|
|
}
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
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;
|
|
|
|
/* 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(".");
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
/* Initialize a parameter that says where MCA param files can
|
|
be found */
|
|
|
|
id = mca_base_param_reg_string_name("mca", "param_files",
|
|
"Path for MCA configuration files containing default parameter values",
|
|
false, false, files, &new_files);
|
|
|
|
/* 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);
|
|
|
|
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);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* 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,
|
|
bool internal,
|
|
bool read_only,
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Register an integer MCA parameter that is not associated with a
|
|
* component
|
|
*/
|
|
int mca_base_param_reg_int_name(const char *type,
|
|
const char *param_name,
|
|
const char *help_msg,
|
|
bool internal,
|
|
bool read_only,
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* 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,
|
|
bool internal,
|
|
bool read_only,
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Register a string MCA parameter that is not associated with a
|
|
* component
|
|
*/
|
|
int mca_base_param_reg_string_name(const char *type,
|
|
const char *param_name,
|
|
const char *help_msg,
|
|
bool internal,
|
|
bool read_only,
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Register an integer MCA parameter
|
|
* (deprecated)
|
|
*/
|
|
int mca_base_param_register_int(const char *type_name,
|
|
const char *component_name,
|
|
const char *param_name,
|
|
const char *mca_param_name,
|
|
int default_value)
|
|
{
|
|
int ret;
|
|
mca_base_param_storage_t storage;
|
|
|
|
storage.intval = default_value;
|
|
ret = param_register(type_name, component_name, param_name, mca_param_name,
|
|
MCA_BASE_PARAM_TYPE_INT, false, false,
|
|
&storage, NULL, NULL, NULL);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* Register a string MCA parameter.
|
|
* (deprecated)
|
|
*/
|
|
int mca_base_param_register_string(const char *type_name,
|
|
const char *component_name,
|
|
const char *param_name,
|
|
const char *mca_param_name,
|
|
const char *default_value)
|
|
{
|
|
int ret;
|
|
mca_base_param_storage_t storage;
|
|
|
|
if (NULL != default_value) {
|
|
storage.stringval = (char *) default_value;
|
|
} else {
|
|
storage.stringval = NULL;
|
|
}
|
|
ret = param_register(type_name, component_name, param_name, mca_param_name,
|
|
MCA_BASE_PARAM_TYPE_STRING, false, false,
|
|
&storage, NULL, NULL, NULL);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* Register a synonym name for an existing MCA parameter
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/*
|
|
* Register a synonym name for an existing MCA parameter
|
|
*/
|
|
int mca_base_param_reg_syn_name(int index_orig,
|
|
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);
|
|
}
|
|
|
|
/*
|
|
* Associate a keyval with a parameter index
|
|
*/
|
|
int mca_base_param_kv_associate(int index, int keyval)
|
|
{
|
|
size_t len;
|
|
mca_base_param_t *array;
|
|
|
|
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 <len, it must be good), so
|
|
save the keyval */
|
|
|
|
array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
|
|
array[index].mbp_keyval = keyval;
|
|
|
|
/* All done */
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Look up an integer MCA parameter.
|
|
*/
|
|
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;
|
|
return OPAL_SUCCESS;
|
|
}
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
|
|
/*
|
|
* Look up an integer MCA parameter, including in attributes
|
|
*/
|
|
int mca_base_param_kv_lookup_int(int index, opal_hash_table_t *attrs,
|
|
int *value)
|
|
{
|
|
mca_base_param_storage_t storage;
|
|
|
|
if (param_lookup(index, &storage, attrs, NULL)) {
|
|
*value = storage.intval;
|
|
return OPAL_SUCCESS;
|
|
}
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
|
|
/*
|
|
* Set an integer parameter
|
|
*/
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Look up a string MCA parameter.
|
|
*/
|
|
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;
|
|
return OPAL_SUCCESS;
|
|
}
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
|
|
/*
|
|
* Look up a string MCA parameter, including in attributes.
|
|
*/
|
|
int mca_base_param_kv_lookup_string(int index, opal_hash_table_t *attrs,
|
|
char **value)
|
|
{
|
|
mca_base_param_storage_t storage;
|
|
|
|
if (param_lookup(index, &storage, attrs, NULL)) {
|
|
*value = storage.stringval;
|
|
return OPAL_SUCCESS;
|
|
}
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
|
|
/*
|
|
* Set an string parameter
|
|
*/
|
|
int mca_base_param_set_string(int index, char *value)
|
|
{
|
|
mca_base_param_storage_t storage;
|
|
|
|
mca_base_param_unset(index);
|
|
storage.stringval = strdup(value);
|
|
param_set_override(index, &storage, MCA_BASE_PARAM_TYPE_STRING);
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Lookup the source of an MCA param's value
|
|
*/
|
|
bool mca_base_param_lookup_source(int index, mca_base_param_source_t *source)
|
|
{
|
|
mca_base_param_storage_t storage;
|
|
|
|
if (param_lookup(index, &storage, NULL, source)) {
|
|
return OPAL_SUCCESS;
|
|
}
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
/*
|
|
* Unset a parameter
|
|
*/
|
|
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);
|
|
if (index < 0 || ((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 <len, it must be good),
|
|
so save the internal flag */
|
|
|
|
array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
|
|
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;
|
|
}
|
|
|
|
|
|
char *mca_base_param_env_var(const char *param_name)
|
|
{
|
|
char *name;
|
|
|
|
asprintf(&name, "%s%s", mca_prefix, param_name);
|
|
|
|
return name;
|
|
}
|
|
|
|
/*
|
|
* Make a string suitable for the environment, setting an MCA param
|
|
*/
|
|
char *mca_base_param_environ_variable(const char *type,
|
|
const char *component,
|
|
const char *param)
|
|
{
|
|
size_t len;
|
|
int id;
|
|
char *ret = NULL, *name;
|
|
mca_base_param_t *array;
|
|
|
|
if (NULL == type) {
|
|
return NULL;
|
|
}
|
|
|
|
id = mca_base_param_find(type, component, param);
|
|
if (OPAL_ERROR != id) {
|
|
array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
|
|
ret = strdup(array[id].mbp_env_var_name);
|
|
} else {
|
|
len = strlen(mca_prefix) + strlen(type) + 16;
|
|
if (NULL != component) {
|
|
len += strlen(component);
|
|
}
|
|
if (NULL != param) {
|
|
len += strlen(param);
|
|
}
|
|
name = (char*)malloc(len);
|
|
if (NULL == name) {
|
|
return NULL;
|
|
}
|
|
name[0] = '\0';
|
|
snprintf(name, len, "%s%s", mca_prefix, type);
|
|
if (NULL != component) {
|
|
strcat(name, "_");
|
|
strcat(name, component);
|
|
}
|
|
if (NULL != param) {
|
|
strcat(name, "_");
|
|
strcat(name, param);
|
|
}
|
|
ret = name;
|
|
}
|
|
|
|
/* All done */
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* Find the index for an MCA parameter based on its names.
|
|
*/
|
|
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;
|
|
}
|
|
|
|
|
|
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 <len, it must be good),
|
|
so save the internal flag */
|
|
|
|
array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
|
|
array[index].mbp_internal = internal;
|
|
|
|
/* All done */
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return a list of info of all currently registered parameters
|
|
*/
|
|
int mca_base_param_dump(opal_list_t **info, bool internal)
|
|
{
|
|
size_t i, j, len;
|
|
mca_base_param_info_t *p, *q;
|
|
mca_base_param_t *array;
|
|
opal_list_item_t *item;
|
|
syn_info_t *si;
|
|
|
|
/* Check for bozo cases */
|
|
|
|
if (!initialized) {
|
|
return OPAL_ERROR;
|
|
}
|
|
|
|
if (NULL == info) {
|
|
return OPAL_ERROR;
|
|
}
|
|
*info = OBJ_NEW(opal_list_t);
|
|
|
|
/* 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) {
|
|
if (array[i].mbp_internal == internal || internal) {
|
|
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_read_only = array[i].mbp_read_only;
|
|
p->mbpp_type = array[i].mbp_type;
|
|
p->mbpp_help_msg = array[i].mbp_help_msg;
|
|
|
|
/* Save this entry to the list */
|
|
opal_list_append(*info, (opal_list_item_t*) p);
|
|
|
|
/* 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);
|
|
printf("*** dumping %d synonyms, too\n",
|
|
p->mbpp_synonyms_len);
|
|
p->mbpp_synonyms = malloc(sizeof(mca_base_param_info_t*) *
|
|
p->mbpp_synonyms_len);
|
|
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;
|
|
q = OBJ_NEW(mca_base_param_info_t);
|
|
if (NULL == q) {
|
|
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_read_only = array[i].mbp_read_only;
|
|
q->mbpp_type = array[i].mbp_type;
|
|
q->mbpp_help_msg = array[i].mbp_help_msg;
|
|
|
|
/* Let this one point to the original */
|
|
q->mbpp_synonym_parent = p;
|
|
|
|
/* Let the original point to this one */
|
|
p->mbpp_synonyms[j] = q;
|
|
|
|
/* Save this entry to the list */
|
|
opal_list_append(*info, (opal_list_item_t*) q);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* All done */
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Make an argv-style list of strings suitable for an environment
|
|
*/
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Free a list -- and all associated memory -- that was previously
|
|
* returned from mca_base_param_dump()
|
|
*/
|
|
int mca_base_param_dump_release(opal_list_t *info)
|
|
{
|
|
opal_list_item_t *item;
|
|
|
|
for (item = opal_list_remove_first(info); NULL != item;
|
|
item = opal_list_remove_first(info)) {
|
|
OBJ_RELEASE(item);
|
|
}
|
|
OBJ_RELEASE(info);
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Shut down the MCA parameter system (normally only invoked by the
|
|
* MCA framework itself).
|
|
*/
|
|
int mca_base_param_finalize(void)
|
|
{
|
|
opal_list_item_t *item;
|
|
mca_base_param_t *array;
|
|
|
|
if (initialized) {
|
|
|
|
/* This is slow, but effective :-) */
|
|
|
|
array = OPAL_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
|
|
while (opal_value_array_get_size(&mca_base_params) > 0) {
|
|
OBJ_DESTRUCT(&array[0]);
|
|
opal_value_array_remove_item(&mca_base_params, 0);
|
|
}
|
|
OBJ_DESTRUCT(&mca_base_params);
|
|
|
|
for (item = opal_list_remove_first(&mca_base_param_file_values);
|
|
NULL != item;
|
|
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;
|
|
}
|
|
|
|
/* 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-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_key)
|
|
{
|
|
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, *tmp_key, *type;
|
|
DWORD dwSize, i, retCode, type_len;
|
|
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. */
|
|
if (cSubKeys) {
|
|
for (i = 0; i < cSubKeys; i++) {
|
|
cbName = MAX_KEY_LENGTH;
|
|
retCode = RegEnumKeyEx(hTestKey, i, achKey, &cbName, NULL, NULL, NULL, NULL);
|
|
if (retCode == ERROR_SUCCESS) {
|
|
asprintf(&sub_sub_key, "%s\\%s", sub_key, achKey);
|
|
if (current_key!=NULL) {
|
|
asprintf(&tmp_key, "%s", current_key);
|
|
asprintf(¤t_key, "%s_%s", current_key, achKey);
|
|
} else {
|
|
tmp_key = NULL;
|
|
asprintf(¤t_key, "%s", achKey);
|
|
}
|
|
read_keys_from_registry(hKey, sub_sub_key, current_key);
|
|
free(current_key);
|
|
if (tmp_key!=NULL) {
|
|
asprintf(¤t_key, "%s", tmp_key);
|
|
free(tmp_key);
|
|
} else
|
|
current_key = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Enumerate the key values. */
|
|
if (cValues) {
|
|
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) {
|
|
cchValue = MAX_VALUE_NAME;
|
|
achValue[0] = '\0';
|
|
retCode = RegEnumValue(hTestKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL);
|
|
|
|
if (retCode == ERROR_SUCCESS ) {
|
|
|
|
/* 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_key!=NULL)
|
|
asprintf(&str_key_name, "%s_%s", current_key, achValue);
|
|
else
|
|
asprintf(&str_key_name, "%s", achValue);
|
|
} else {
|
|
if (current_key!=NULL)
|
|
asprintf(&str_key_name, "%s", current_key);
|
|
else
|
|
asprintf(&str_key_name, "%s", achValue);
|
|
}
|
|
|
|
type_len = strcspn(str_key_name, "_");
|
|
type = (char*) malloc((type_len+1)*sizeof(char));
|
|
strncpy( type, str_key_name, type_len );
|
|
if ( type_len == strlen(str_key_name) )
|
|
strcpy( str_key_name, "" );
|
|
else
|
|
strcpy( str_key_name, str_key_name + type_len + 1 ); /* trim str_key_name by length of type + 1 for underscrore */
|
|
type[type_len]='\0';
|
|
if (lpType == (LPDWORD) REG_SZ) { /* REG_SZ = 1 */
|
|
retCode = RegQueryValueEx(hTestKey, achValue, NULL, NULL, (LPBYTE)&str_lpData, &dwSize);
|
|
if (!retCode) {
|
|
mca_base_param_storage_t storage, override;
|
|
mca_base_param_storage_t lookup;
|
|
|
|
storage.stringval = (char*)str_lpData;
|
|
override.stringval = (char*)str_lpData;
|
|
(void)param_register( type, NULL, str_key_name, "Key read from Windows registry",
|
|
MCA_BASE_PARAM_TYPE_STRING, false, false,
|
|
&storage, NULL, &override,
|
|
&lookup );
|
|
/*printf( "%s %s = %s.\n", type, str_key_name, str_lpData);*/
|
|
} else {
|
|
opal_output( 0, "error reading value of param_name: %s with %d error.\n",
|
|
str_key_name, retCode);
|
|
}
|
|
}
|
|
if (lpType == (LPDWORD) REG_DWORD) { /* REG_DWORD = 4 */
|
|
retCode = RegQueryValueEx(hTestKey, achValue, NULL, NULL, (LPBYTE)&word_lpData, &dwSize);
|
|
if (!retCode) {
|
|
storage.intval = (int)word_lpData;
|
|
override.intval = (int)word_lpData;
|
|
(void)param_register( type, NULL, str_key_name, "Key read from Windows registry",
|
|
MCA_BASE_PARAM_TYPE_INT, false, false,
|
|
&storage, NULL, &override,
|
|
&lookup );
|
|
/*printf( "%s %s = %d.\n", type, str_key_name, (int)word_lpData);*/
|
|
} else {
|
|
opal_output( 0, "error reading value of param_name: %s with %d error.\n",
|
|
str_key_name, retCode );
|
|
}
|
|
}
|
|
free(type);
|
|
free(str_key_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 */
|
|
OMPI_DEBUG_ZERO(param);
|
|
|
|
/* Initialize the array if it has never been initialized */
|
|
|
|
if (!initialized) {
|
|
mca_base_param_init();
|
|
}
|
|
|
|
/* Create a parameter entry. If a keyval is to be used, it will be
|
|
registered elsewhere. We simply assign -1 here. */
|
|
|
|
OBJ_CONSTRUCT(¶m, mca_base_param_t);
|
|
param.mbp_type = type;
|
|
param.mbp_keyval = -1;
|
|
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 see
|
|
if we're 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;
|
|
}
|
|
}
|
|
|
|
/* Original is INT, new is STRING */
|
|
|
|
else if (MCA_BASE_PARAM_TYPE_INT == array[i].mbp_type &&
|
|
MCA_BASE_PARAM_TYPE_STRING == param.mbp_type) {
|
|
if (NULL != default_value &&
|
|
NULL != param.mbp_default_value.stringval) {
|
|
array[i].mbp_default_value.stringval =
|
|
strdup(param.mbp_default_value.stringval);
|
|
}
|
|
|
|
if (NULL != file_value &&
|
|
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 &&
|
|
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;
|
|
}
|
|
|
|
array[i].mbp_type = param.mbp_type;
|
|
}
|
|
|
|
/* Original is STRING, new is INT */
|
|
|
|
else if (MCA_BASE_PARAM_TYPE_STRING == array[i].mbp_type &&
|
|
MCA_BASE_PARAM_TYPE_INT == 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.intval =
|
|
param.mbp_default_value.intval;
|
|
}
|
|
if (NULL != file_value) {
|
|
if (NULL != array[i].mbp_file_value.stringval) {
|
|
free(array[i].mbp_file_value.stringval);
|
|
}
|
|
array[i].mbp_file_value.intval =
|
|
param.mbp_file_value.intval;
|
|
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.intval =
|
|
param.mbp_override_value.intval;
|
|
array[i].mbp_override_value_set = true;
|
|
}
|
|
|
|
array[i].mbp_type = param.mbp_type;
|
|
}
|
|
|
|
/* 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);
|
|
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;
|
|
}
|
|
}
|
|
array[index].mbp_override_value_set = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
* Lookup a parameter in multiple places
|
|
*/
|
|
static bool param_lookup(size_t index, mca_base_param_storage_t *storage,
|
|
opal_hash_table_t *attrs,
|
|
mca_base_param_source_t *source_param)
|
|
{
|
|
size_t size;
|
|
mca_base_param_t *array;
|
|
char *p, *q;
|
|
mca_base_param_source_t source = MCA_BASE_PARAM_SOURCE_MAX;
|
|
|
|
/* 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_keyvals(&array[index], storage, attrs) ||
|
|
lookup_env(&array[index], storage) ||
|
|
lookup_file(&array[index], storage)) {
|
|
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_keyvals(&array[index], storage, attrs)) {
|
|
source = MCA_BASE_PARAM_SOURCE_KEYVAL;
|
|
} else if (lookup_env(&array[index], storage)) {
|
|
source = MCA_BASE_PARAM_SOURCE_ENV;
|
|
} else if (lookup_file(&array[index], storage)) {
|
|
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 set of attributes/keyvals
|
|
*/
|
|
static bool lookup_keyvals(mca_base_param_t *param,
|
|
mca_base_param_storage_t *storage,
|
|
opal_hash_table_t *attrs)
|
|
{
|
|
#if 1
|
|
/* JMS: Comment this out for now, because it drags in all of
|
|
libmpi. This is undesirable for programs like mpirun, etc.
|
|
Need a better solution for this -- perhaps a registration kind
|
|
of thing...? */
|
|
return false;
|
|
#else
|
|
int err, flag;
|
|
|
|
/* If this param has a keyval and we were provided with a hash
|
|
table, look it up and see if we can find a value */
|
|
|
|
if (-1 != param->mbp_keyval) {
|
|
|
|
/* Use the stringval member of the union because it's definitely
|
|
big enough to handle both (int) and (char*) */
|
|
|
|
err = ompi_attr_get(attrs, param->mbp_keyval,
|
|
&storage->stringval, &flag);
|
|
if (OPAL_SUCCESS == err && 1 == flag) {
|
|
|
|
/* Because of alignment weirdness between (void*) and int, we
|
|
must grab the lower sizeof(int) bytes from the (char*) in
|
|
stringval, in case sizeof(int) != sizeof(char*). */
|
|
|
|
if (MCA_BASE_PARAM_TYPE_INT == param->mbp_type) {
|
|
storage->intval = *((int *) (storage->stringval +
|
|
sizeof(void *) - sizeof(int)));
|
|
}
|
|
|
|
/* Nothing to do for string -- we already have the value loaded
|
|
in the right place */
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/* Either this param has not keyval or we didn't find the keyval */
|
|
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
* 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;
|
|
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)
|
|
{
|
|
bool found = false;
|
|
syn_info_t *si;
|
|
char *deprecated_name;
|
|
opal_list_item_t *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) {
|
|
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 (item = opal_list_get_first(param->mbp_synonyms);
|
|
opal_list_get_end(param->mbp_synonyms) != item;
|
|
item = opal_list_get_next(item)) {
|
|
si = (syn_info_t*) 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;
|
|
}
|
|
param->mbp_file_value_set = true;
|
|
|
|
/* 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_keyval = -1;
|
|
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_override_value_set = false;
|
|
p->mbp_override_value.stringval = NULL;
|
|
|
|
p->mbp_synonyms = NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* Free all the contents of a param container
|
|
*/
|
|
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->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 &&
|
|
NULL != p->mbp_file_value.stringval) {
|
|
free(p->mbp_file_value.stringval);
|
|
}
|
|
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);
|
|
}
|
|
|
|
#if OMPI_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;
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
fv_constructor(f);
|
|
}
|
|
|
|
static void info_constructor(mca_base_param_info_t *p)
|
|
{
|
|
p->mbpp_index = -1;
|
|
p->mbpp_type = MCA_BASE_PARAM_TYPE_MAX;
|
|
|
|
p->mbpp_type_name = NULL;
|
|
p->mbpp_component_name = NULL;
|
|
p->mbpp_param_name = NULL;
|
|
p->mbpp_full_name = NULL;
|
|
|
|
p->mbpp_deprecated = false;
|
|
|
|
p->mbpp_synonyms = NULL;
|
|
p->mbpp_synonyms_len = 0;
|
|
p->mbpp_synonym_parent = NULL;
|
|
|
|
p->mbpp_read_only = false;
|
|
p->mbpp_help_msg = NULL;
|
|
}
|
|
|
|
static void info_destructor(mca_base_param_info_t *p)
|
|
{
|
|
if (NULL != p->mbpp_synonyms) {
|
|
free(p->mbpp_synonyms);
|
|
}
|
|
/* No need to free any of the strings -- the pointers were copied
|
|
by value from their corresponding parameter registration */
|
|
|
|
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);
|
|
}
|