mca/base: add support for component aliasing
This commit adds support for aliasing component names. A component name alias is created by calling: mca_base_alias_register. The name of the project and framework are optional. The component name and component alias are required. Once an alias is registered all variables registered after the alias creation will have synonyms also registered. For example: ```c mca_base_alias_register("opal", "btl", "vader", "sm", false); ``` would cause all of the variables registered by btl/vader to have aliases that start with btl_sm. Ex: btl_vader_single_copy_mechanism would have the synonym: btl_sm_single_copy_mechanism. If aliases are registered before component filtering the alias can also be used for component selection. For example, if sm is registered as an alias to vader in the btl framework register function then ```--mca btl self,sm``` would be equivalent to ```--mca btl self,vader```. Signed-off-by: Nathan Hjelm <hjelmn@google.com>
Этот коммит содержится в:
родитель
3a036f8486
Коммит
9fae5bfdf3
@ -10,6 +10,7 @@
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
|
||||
# Copyright (c) 2020 Google LLC. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
@ -31,6 +32,7 @@ dist_opaldata_DATA = help-mca-base.txt help-mca-var.txt
|
||||
|
||||
headers = \
|
||||
base.h \
|
||||
mca_base_alias.h \
|
||||
mca_base_component_repository.h \
|
||||
mca_base_var.h \
|
||||
mca_base_pvar.h \
|
||||
@ -43,6 +45,7 @@ headers = \
|
||||
|
||||
libmca_base_la_SOURCES = \
|
||||
$(headers) \
|
||||
mca_base_alias.c \
|
||||
mca_base_close.c \
|
||||
mca_base_cmd_line.c \
|
||||
mca_base_component_compare.c \
|
||||
|
173
opal/mca/base/mca_base_alias.c
Обычный файл
173
opal/mca/base/mca_base_alias.c
Обычный файл
@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 Google, LLC. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mca_base_alias.h"
|
||||
#include "opal/class/opal_hash_table.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
|
||||
static void mca_base_alias_init (mca_base_alias_t *alias)
|
||||
{
|
||||
OBJ_CONSTRUCT(&alias->component_aliases, opal_list_t);
|
||||
}
|
||||
|
||||
static void mca_base_alias_fini (mca_base_alias_t *alias)
|
||||
{
|
||||
OPAL_LIST_DESTRUCT(&alias->component_aliases);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(mca_base_alias_t, opal_object_t, mca_base_alias_init,
|
||||
mca_base_alias_fini);
|
||||
|
||||
static void mca_base_alias_item_init (mca_base_alias_item_t *alias_item) {
|
||||
alias_item->component_alias = NULL;
|
||||
}
|
||||
|
||||
static void mca_base_alias_item_fini (mca_base_alias_item_t *alias_item) {
|
||||
free (alias_item->component_alias);
|
||||
}
|
||||
|
||||
OBJ_CLASS_INSTANCE(mca_base_alias_item_t, opal_list_item_t, mca_base_alias_item_init,
|
||||
mca_base_alias_item_fini);
|
||||
|
||||
/*
|
||||
* local variables
|
||||
*/
|
||||
static opal_hash_table_t *alias_hash_table;
|
||||
|
||||
static void mca_base_alias_cleanup (void)
|
||||
{
|
||||
if (!alias_hash_table) {
|
||||
return;
|
||||
}
|
||||
|
||||
void *key;
|
||||
opal_object_t *value;
|
||||
OPAL_HASH_TABLE_FOREACH_PTR(key, value, alias_hash_table, {
|
||||
OBJ_RELEASE(value);
|
||||
});
|
||||
|
||||
OBJ_RELEASE(alias_hash_table);
|
||||
alias_hash_table = NULL;
|
||||
}
|
||||
|
||||
static int mca_base_alias_setup (void)
|
||||
{
|
||||
if (NULL != alias_hash_table) {
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
opal_finalize_register_cleanup (mca_base_alias_cleanup);
|
||||
|
||||
alias_hash_table = OBJ_NEW(opal_hash_table_t);
|
||||
if (NULL == alias_hash_table) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
int ret = opal_hash_table_init (alias_hash_table, 32);
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
OBJ_RELEASE(alias_hash_table);
|
||||
alias_hash_table = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
static char *mca_base_alias_generate_name (const char *project, const char *framework, const char *component_name)
|
||||
{
|
||||
size_t project_length = project ? strlen (project) : 0;
|
||||
size_t framework_length = framework ? strlen (framework) : 0;
|
||||
size_t component_name_length = strlen (component_name);
|
||||
size_t length = project_length + framework_length + component_name_length + 2;
|
||||
char *tmp = calloc (1, length + 1);
|
||||
if (NULL == tmp) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (project_length) {
|
||||
strncat (tmp, project, length);
|
||||
strncat (tmp, "_", 1);
|
||||
length -= project_length + 1;
|
||||
}
|
||||
|
||||
if (framework_length) {
|
||||
strncat (tmp, framework, length);
|
||||
strncat (tmp, "_", 1);
|
||||
length -= framework_length + 1;
|
||||
}
|
||||
|
||||
strncat (tmp, component_name, length);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static mca_base_alias_t *mca_base_alias_lookup_internal (const char *name)
|
||||
{
|
||||
mca_base_alias_t *alias = NULL;
|
||||
if (NULL == alias_hash_table) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) opal_hash_table_get_value_ptr (alias_hash_table, name, strlen (name), (void **) &alias);
|
||||
return alias;
|
||||
}
|
||||
|
||||
int mca_base_alias_register (const char *project, const char *framework, const char *component_name,
|
||||
const char *component_alias, uint32_t alias_flags)
|
||||
{
|
||||
if (NULL == component_name) {
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
int ret = mca_base_alias_setup ();
|
||||
if (OPAL_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *name = mca_base_alias_generate_name (project, framework, component_name);
|
||||
assert (NULL != name);
|
||||
|
||||
mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
|
||||
if (NULL == alias) {
|
||||
alias = OBJ_NEW(mca_base_alias_t);
|
||||
if (NULL == alias) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
opal_hash_table_set_value_ptr (alias_hash_table, name, strlen(name), alias);
|
||||
free (name);
|
||||
}
|
||||
|
||||
mca_base_alias_item_t *alias_item = OBJ_NEW(mca_base_alias_item_t);
|
||||
if (NULL == alias_item) {
|
||||
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
alias_item->component_alias = strdup (component_alias);
|
||||
alias_item->alias_flags = alias_flags;
|
||||
|
||||
opal_list_append (&alias->component_aliases, &alias_item->super);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
const mca_base_alias_t *mca_base_alias_lookup(const char *project, const char *framework, const char *component_name)
|
||||
{
|
||||
if (NULL == component_name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *name = mca_base_alias_generate_name (project, framework, component_name);
|
||||
assert (NULL != name);
|
||||
const mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
|
||||
free (name);
|
||||
|
||||
return alias;
|
||||
}
|
86
opal/mca/base/mca_base_alias.h
Обычный файл
86
opal/mca/base/mca_base_alias.h
Обычный файл
@ -0,0 +1,86 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2020 Google, LLC. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OPAL_MCA_BASE_ALIAS_H
|
||||
#define OPAL_MCA_BASE_ALIAS_H
|
||||
|
||||
#include "opal_config.h"
|
||||
#include "opal/class/opal_list.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
enum mca_base_alias_flags_t {
|
||||
MCA_BASE_ALIAS_FLAG_NONE = 0,
|
||||
/** The aliased name has been deprecated. */
|
||||
MCA_BASE_ALIAS_FLAG_DEPRECATED = 1,
|
||||
};
|
||||
|
||||
typedef enum mca_base_alias_flags_t mca_base_alias_flags_t;
|
||||
|
||||
struct mca_base_alias_item_t {
|
||||
opal_list_item_t super;
|
||||
/** Name aias. */
|
||||
char *component_alias;
|
||||
/** Alias flags. */
|
||||
uint32_t alias_flags;
|
||||
};
|
||||
|
||||
typedef struct mca_base_alias_item_t mca_base_alias_item_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(mca_base_alias_item_t);
|
||||
|
||||
struct mca_base_alias_t {
|
||||
opal_object_t super;
|
||||
/** List of name aliases. */
|
||||
opal_list_t component_aliases;
|
||||
};
|
||||
|
||||
typedef struct mca_base_alias_t mca_base_alias_t;
|
||||
|
||||
OBJ_CLASS_DECLARATION(mca_base_alias_t);
|
||||
|
||||
/**
|
||||
* @brief Create a alias for a component name.
|
||||
*
|
||||
* @param[in] project Project name (may be NULL)
|
||||
* @param[in] framework Framework name (may be NULL)
|
||||
* @param[in] component_name Name of component to alias (may not be NULL)
|
||||
* @param[in] component_alias Aliased name (may not be NULL)
|
||||
* @param[in] alias_flags Flags (see mca_base_alias_flags_t)
|
||||
*
|
||||
* This function aliases one component name to another. When aliased
|
||||
* any variable registered with this project, framework, and
|
||||
* component_name will have synonyms created. For example, if
|
||||
* opal_btl_vader is aliased to sm then registers a variable
|
||||
* named btl_vader_flags then a synonym will be created with the
|
||||
* name btl_sm_flags. If an alias is registered early enough
|
||||
* (during framework registration for example) then the alias can
|
||||
* also be used for component selection. In the previous example
|
||||
* --mca btl vader and --mca btl sm would select the same
|
||||
* component if the synonym is registered in the btl framework
|
||||
* registration function.
|
||||
*/
|
||||
OPAL_DECLSPEC int mca_base_alias_register (const char *project, const char *framework,
|
||||
const char *component_name,
|
||||
const char *component_alias,
|
||||
uint32_t alias_flags);
|
||||
|
||||
/**
|
||||
* @brief Check for aliases for a component.
|
||||
*
|
||||
* @param[in] project Project name (may be NULL)
|
||||
* @param[in] frameworek Framework name (may be NULL)
|
||||
* @param[in] component_name Component name (may not be NULL)
|
||||
*/
|
||||
OPAL_DECLSPEC const mca_base_alias_t *mca_base_alias_lookup(const char *project,
|
||||
const char *framework,
|
||||
const char *component_name);
|
||||
|
||||
#endif /* OPAL_MCA_BASE_ALIAS_H */
|
@ -18,6 +18,7 @@
|
||||
* reserved.
|
||||
* Copyright (c) 2019 Triad National Security, LLC. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2020 Google, LLC. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -56,6 +57,7 @@
|
||||
#include "opal/class/opal_list.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/mca/base/mca_base_alias.h"
|
||||
#include "opal/mca/base/mca_base_component_repository.h"
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/dl/base/base.h"
|
||||
@ -84,7 +86,8 @@ typedef struct mca_base_open_only_dummy_component_t mca_base_open_only_dummy_com
|
||||
|
||||
static char negate[] = "^";
|
||||
|
||||
static bool use_component(const bool include_mode,
|
||||
static bool use_component(const mca_base_framework_t *framework,
|
||||
const bool include_mode,
|
||||
const char **requested_component_names,
|
||||
const char *component_name);
|
||||
|
||||
@ -118,7 +121,7 @@ int mca_base_component_find (const char *directory, mca_base_framework_t *framew
|
||||
/* Find all the components that were statically linked in */
|
||||
if (static_components) {
|
||||
for (int i = 0 ; NULL != static_components[i]; ++i) {
|
||||
if ( use_component(include_mode,
|
||||
if ( use_component(framework, include_mode,
|
||||
(const char**)requested_component_names,
|
||||
static_components[i]->mca_component_name) ) {
|
||||
cli = OBJ_NEW(mca_base_component_list_item_t);
|
||||
@ -192,7 +195,7 @@ int mca_base_components_filter (mca_base_framework_t *framework, uint32_t filter
|
||||
mca_base_open_only_dummy_component_t *dummy =
|
||||
(mca_base_open_only_dummy_component_t *) cli->cli_component;
|
||||
|
||||
can_use = use_component (include_mode, (const char **) requested_component_names,
|
||||
can_use = use_component (framework, include_mode, (const char **) requested_component_names,
|
||||
cli->cli_component->mca_component_name);
|
||||
|
||||
if (!can_use || (filter_flags & dummy->data.param_field) != filter_flags) {
|
||||
@ -263,7 +266,7 @@ static void find_dyn_components(const char *path, mca_base_framework_t *framewor
|
||||
|
||||
/* Iterate through the repository and find components that can be included */
|
||||
OPAL_LIST_FOREACH(ri, dy_components, mca_base_component_repository_item_t) {
|
||||
if (use_component(include_mode, names, ri->ri_name)) {
|
||||
if (use_component(framework, include_mode, names, ri->ri_name)) {
|
||||
mca_base_component_repository_open (framework, ri);
|
||||
}
|
||||
}
|
||||
@ -271,27 +274,44 @@ static void find_dyn_components(const char *path, mca_base_framework_t *framewor
|
||||
|
||||
#endif /* OPAL_HAVE_DL_SUPPORT */
|
||||
|
||||
static bool use_component(const bool include_mode,
|
||||
static bool component_in_list (const char **requested_component_names,
|
||||
const char *component_name)
|
||||
{
|
||||
for (int i = 0 ; requested_component_names[i] ; ++i) {
|
||||
if (strcmp(component_name, requested_component_names[i]) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool use_component(const mca_base_framework_t *framework,
|
||||
const bool include_mode,
|
||||
const char **requested_component_names,
|
||||
const char *component_name)
|
||||
{
|
||||
bool found = false;
|
||||
const char **req_comp_name = requested_component_names;
|
||||
|
||||
/*
|
||||
* If no selection is specified then we use all components
|
||||
* we can find.
|
||||
*/
|
||||
if (NULL == req_comp_name) {
|
||||
if (NULL == requested_component_names) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while ( *req_comp_name != NULL ) {
|
||||
if ( strcmp(component_name, *req_comp_name) == 0 ) {
|
||||
found = true;
|
||||
bool found = component_in_list (requested_component_names, component_name);
|
||||
|
||||
if (!found) {
|
||||
const mca_base_alias_t *alias = mca_base_alias_lookup (framework->framework_project,
|
||||
framework->framework_name, component_name);
|
||||
if (alias) {
|
||||
OPAL_LIST_FOREACH_DECL(alias_item, &alias->component_aliases, mca_base_alias_item_t) {
|
||||
found = component_in_list (requested_component_names, alias_item->component_alias);
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
req_comp_name++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -315,21 +335,34 @@ static bool use_component(const bool include_mode,
|
||||
static int component_find_check (mca_base_framework_t *framework, char **requested_component_names)
|
||||
{
|
||||
opal_list_t *components = &framework->framework_components;
|
||||
mca_base_component_list_item_t *cli;
|
||||
|
||||
if (NULL == requested_component_names) {
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 0; NULL != requested_component_names[i]; ++i) {
|
||||
for (int i = 0 ; requested_component_names[i] ; ++i) {
|
||||
bool found = false;
|
||||
|
||||
OPAL_LIST_FOREACH(cli, components, mca_base_component_list_item_t) {
|
||||
if (0 == strcmp(requested_component_names[i],
|
||||
cli->cli_component->mca_component_name)) {
|
||||
OPAL_LIST_FOREACH_DECL(cli, components, mca_base_component_list_item_t) {
|
||||
if (0 == strcmp (requested_component_names[i], cli->cli_component->mca_component_name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const mca_base_alias_t *alias = mca_base_alias_lookup (framework->framework_project,
|
||||
framework->framework_name,
|
||||
cli->cli_component->mca_component_name);
|
||||
if (alias) {
|
||||
OPAL_LIST_FOREACH_DECL(alias_item, &alias->component_aliases, mca_base_alias_item_t) {
|
||||
if (0 == strcmp (requested_component_names[i], alias_item->component_alias)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
* Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
|
||||
* Copyright (c) 2018 Triad National Security, LLC. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2020 Google, LLC. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -49,6 +50,7 @@
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/mca_base_vari.h"
|
||||
#include "opal/mca/base/mca_base_alias.h"
|
||||
#include "opal/constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/opal_environ.h"
|
||||
@ -1545,12 +1547,33 @@ int mca_base_var_register (const char *project_name, const char *framework_name,
|
||||
mca_base_var_info_lvl_t info_lvl,
|
||||
mca_base_var_scope_t scope, void *storage)
|
||||
{
|
||||
int ret;
|
||||
/* Only integer variables can have enumerator */
|
||||
assert (NULL == enumerator || (MCA_BASE_VAR_TYPE_INT == type || MCA_BASE_VAR_TYPE_UNSIGNED_INT == type));
|
||||
|
||||
return register_variable (project_name, framework_name, component_name,
|
||||
ret = register_variable (project_name, framework_name, component_name,
|
||||
variable_name, description, type, enumerator,
|
||||
bind, flags, info_lvl, scope, -1, storage);
|
||||
if (OPAL_UNLIKELY(0 > ret)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Register aliases if any exist */
|
||||
const mca_base_alias_t *alias = mca_base_alias_lookup (project_name, framework_name, component_name);
|
||||
if (NULL == alias) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
OPAL_LIST_FOREACH_DECL(alias_item, &alias->component_aliases, mca_base_alias_item_t) {
|
||||
mca_base_var_syn_flag_t flags = 0;
|
||||
if (alias_item->alias_flags & MCA_BASE_ALIAS_FLAG_DEPRECATED) {
|
||||
flags = MCA_BASE_VAR_SYN_FLAG_DEPRECATED;
|
||||
}
|
||||
(void) mca_base_var_register_synonym (ret, project_name, framework_name, alias_item->component_alias,
|
||||
variable_name, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mca_base_component_var_register (const mca_base_component_t *component,
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user