2
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3
* University Research and Technology
4
* Corporation. All rights reserved.
5
* Copyright (c) 2004-2005 The University of Tennessee and The University
6
* of Tennessee Research Foundation. All rights
8
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9
* University of Stuttgart. All rights reserved.
10
* Copyright (c) 2004-2005 The Regents of the University of California.
11
* All rights reserved.
14
* Additional copyrights may follow
19
#include "opal_config.h"
25
#include "opal/class/opal_list.h"
26
#include "opal/util/strncpy.h"
27
#include "opal/util/argv.h"
28
#include "opal/util/output.h"
29
#include "opal/util/show_help.h"
30
#include "opal/mca/mca.h"
31
#include "opal/mca/base/base.h"
32
#include "opal/mca/base/mca_base_component_repository.h"
33
#include "opal/constants.h"
35
struct component_name_t {
36
opal_list_item_t super;
38
char mn_name[MCA_BASE_MAX_COMPONENT_NAME_LEN];
40
typedef struct component_name_t component_name_t;
46
static bool show_errors = false;
47
static const char negate = '^';
53
static int parse_requested(int mca_param, bool *include_mode,
54
char ***requested_component_names);
55
static int open_components(const char *type_name, int output_id,
56
opal_list_t *src, opal_list_t *dest);
57
static int distill(bool include_mode, const char *type_name,
58
int output_id, opal_list_t *src, opal_list_t *dest,
63
* Function for finding and opening either all MCA components, or the
64
* one that was specifically requested via a MCA parameter.
66
int mca_base_components_open(const char *type_name, int output_id,
67
const mca_base_component_t **static_components,
68
opal_list_t *components_available,
69
bool open_dso_components)
72
opal_list_item_t *item;
73
opal_list_t components_found, components_distilled;
74
char **requested_component_names;
75
int param_verbose = -1;
80
bool distilled = false;
82
/* Register MCA parameters */
84
asprintf(&str, "Default selection set of components for the %s framework (<none> means \"use all components that can be found\")", type_name);
86
mca_base_param_reg_string_name(type_name, NULL, str,
87
false, false, NULL, NULL);
90
asprintf(&str, "Verbosity level for the %s framework (0 = no verbosity)", type_name);
92
mca_base_param_reg_int_name(type_name, "base_verbose",
93
str, false, false, 0, NULL);
96
param = mca_base_param_find("mca", NULL, "component_show_load_errors");
97
mca_base_param_lookup_int(param, &ret);
98
show_errors = (0 != ret) ? true : false;
100
/* Setup verbosity for this MCA type */
102
mca_base_param_lookup_int(param_verbose, &verbose_level);
103
if (output_id != 0) {
104
opal_output_set_verbosity(output_id, verbose_level);
106
opal_output_verbose(10, output_id,
107
"mca: base: components_open: Looking for %s components",
110
/* Find and load all available components */
113
mca_base_component_find(NULL, type_name, static_components,
114
&components_found, open_dso_components)) {
118
/* See if one or more specific components were requested */
120
ret = parse_requested(param_type, &include_mode, &requested_component_names);
121
if (OPAL_SUCCESS == ret) {
122
ret = distill(include_mode, type_name, output_id, &components_found,
123
&components_distilled, requested_component_names);
127
/* Now open whatever we have left */
129
if (OPAL_SUCCESS == ret) {
130
ret = open_components(type_name, output_id,
131
&components_distilled, components_available);
136
for (item = opal_list_remove_first(&components_found); NULL != item;
137
item = opal_list_remove_first(&components_found)) {
140
OBJ_DESTRUCT(&components_found);
142
for (item = opal_list_remove_first(&components_distilled); NULL != item;
143
item = opal_list_remove_first(&components_distilled)) {
146
OBJ_DESTRUCT(&components_distilled);
148
if (NULL != requested_component_names) {
149
opal_argv_free(requested_component_names);
158
static int parse_requested(int mca_param, bool *include_mode,
159
char ***requested_component_names)
165
*requested_component_names = NULL;
166
*include_mode = true;
168
/* See if the user requested anything */
170
if (OPAL_ERROR == mca_base_param_lookup_string(mca_param, &requested)) {
173
if (NULL == requested || 0 == strlen(requested)) {
176
*requested_component_names = opal_argv_split(requested, ',');
178
/* Are we including or excluding? */
180
for (i = 0; NULL != (*requested_component_names)[i]; ++i) {
181
if (negate == *((*requested_component_names)[i])) {
182
tmp = strdup((*requested_component_names)[i] + 1);
183
free((*requested_component_names)[i]);
184
(*requested_component_names)[i] = tmp;
186
*include_mode = false;
197
* Parse the list of found components and factor in the included /
198
* excluded names to come up with a distilled list of components that
199
* we should try to open.
201
static int distill(bool include_mode, const char *type_name,
202
int output_id, opal_list_t *src, opal_list_t *dest,
207
opal_list_item_t *item, *next;
208
const mca_base_component_t *component;
209
mca_base_component_list_item_t *cli;
211
opal_output_verbose(10, output_id,
212
"mca: base: components_open: "
213
"distilling %s components", type_name);
214
OBJ_CONSTRUCT(dest, opal_list_t);
219
opal_output_verbose(10, output_id,
220
"mca: base: components_open: "
221
"accepting all %s components", type_name);
222
opal_list_join(dest, opal_list_get_end(dest), src);
226
/* Are we including components? */
229
opal_output_verbose(10, output_id,
230
"mca: base: components_open: "
231
"including %s components", type_name);
233
/* Go through all the components and only keep the ones that
234
are specifically mentioned in the list */
236
for (i = 0; NULL != names[i]; ++i) {
239
for (item = opal_list_get_first(src);
240
opal_list_get_end(src) != item;
242
next = opal_list_get_next(item);
243
cli = (mca_base_component_list_item_t *) item;
244
component = cli->cli_component;
245
if (0 == strcmp(names[i], component->mca_component_name)) {
246
opal_list_remove_item(src, item);
247
opal_list_append(dest, item);
254
opal_output_verbose(10, output_id,
255
"mca: base: components_open: "
256
"%s --> included", names[i]);
258
opal_output_verbose(10, output_id,
259
"mca: base: components_open: "
260
"%s --> not found", names[i]);
265
/* No, we are excluding components */
268
opal_output_verbose(10, output_id,
269
"mca: base: components_open: "
270
"excluding %s components", type_name);
272
/* Go through all the components and only keep the ones that
273
are specifically mentioned in the list */
275
for (item = opal_list_get_first(src);
276
opal_list_get_end(src) != item;
278
next = opal_list_get_next(item);
280
cli = (mca_base_component_list_item_t *) item;
281
component = cli->cli_component;
283
for (i = 0; NULL != names[i]; ++i) {
284
if (0 == strcmp(names[i], component->mca_component_name)) {
291
opal_output_verbose(10, output_id,
292
"mca: base: components_open: "
294
component->mca_component_name);
296
opal_list_remove_item(src, item);
297
opal_list_append(dest, item);
298
opal_output_verbose(10, output_id,
299
"mca: base: components_open: "
301
component->mca_component_name);
313
* Traverse the entire list of found components (a list of
314
* mca_base_component_t instances). If the requested_component_names
315
* array is empty, or the name of each component in the list of found
316
* components is in the requested_components_array, try to open it.
317
* If it opens, add it to the components_available list.
319
static int open_components(const char *type_name, int output_id,
320
opal_list_t *src, opal_list_t *dest)
322
opal_list_item_t *item;
323
const mca_base_component_t *component;
324
mca_base_component_list_item_t *cli;
330
opal_output_verbose(10, output_id,
331
"mca: base: components_open: opening %s components",
334
/* Traverse the list of found components */
336
OBJ_CONSTRUCT(dest, opal_list_t);
337
for (item = opal_list_get_first(src);
338
opal_list_get_end(src) != item;
339
item = opal_list_get_next(item)) {
340
cli = (mca_base_component_list_item_t *) item;
341
component = cli->cli_component;
343
opened = called_open = false;
344
opal_output_verbose(10, output_id,
345
"mca: base: components_open: found loaded component %s",
346
component->mca_component_name);
348
if (NULL == component->mca_open_component) {
350
opal_output_verbose(10, output_id,
351
"mca: base: components_open: "
352
"component %s has no open function",
353
component->mca_component_name);
356
if (MCA_SUCCESS == component->mca_open_component()) {
358
opal_output_verbose(10, output_id,
359
"mca: base: components_open: "
360
"component %s open function successful",
361
component->mca_component_name);
363
/* We may end up displaying this twice, but it may go
364
to separate streams. So better to be redundant
365
than to not display the error in the stream where
369
opal_output(0, "mca: base: components_open: "
370
"component %s / %s open function failed",
371
component->mca_type_name,
372
component->mca_component_name);
374
opal_output_verbose(10, output_id,
375
"mca: base: components_open: "
376
"component %s open function failed",
377
component->mca_component_name);
381
/* If it didn't open, close it out and get rid of it */
385
if (NULL != component->mca_close_component) {
386
component->mca_close_component();
388
opal_output_verbose(10, output_id,
389
"mca: base: components_open: component %s closed",
390
component->mca_component_name);
393
mca_base_component_repository_release(component);
394
opal_output_verbose(10, output_id,
395
"mca: base: components_open: component %s unloaded",
396
component->mca_component_name);
399
/* If it did open, register its "priority" MCA parameter (if
400
it doesn't already have one) and save it in the
401
opened_components list */
404
if (OPAL_ERROR == mca_base_param_find(type_name,
405
component->mca_component_name,
407
mca_base_param_register_int(type_name,
408
component->mca_component_name,
409
"priority", NULL, 0);
412
cli = OBJ_NEW(mca_base_component_list_item_t);
414
return OPAL_ERR_OUT_OF_RESOURCE;
416
cli->cli_component = component;
417
opal_list_append(dest, (opal_list_item_t *) cli);