2 * Copyright (c) 2004-2008 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.
12 * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
15 * Additional copyrights may follow
21 #include "orte_config.h"
27 #include "opal/mca/mca.h"
28 #include "opal/util/argv.h"
29 #include "opal/mca/base/base.h"
30 #include "opal/util/output.h"
32 #include "orte/mca/notifier/base/base.h"
34 #if !ORTE_DISABLE_FULL_SUPPORT
36 /* Global variables */
38 * orte_notifier_base_XXX_selected is set to true if at least 1 module has
39 * been selected for the notifier XXX API interface.
41 bool orte_notifier_base_log_selected = false;
42 bool orte_notifier_base_help_selected = false;
43 bool orte_notifier_base_log_peer_selected = false;
44 bool orte_notifier_base_log_event_selected = false;
46 static inline char **orte_notifier_get_include_list(const char *,
49 static bool orte_notifier_add_module(mca_base_component_t *component,
50 orte_notifier_base_module_t *module,
53 opal_list_t *selected_modules);
55 static void onbsp_construct(orte_notifier_base_selected_pair_t *obj)
57 obj->onbsp_component = NULL;
58 obj->onbsp_module = NULL;
59 obj->onbsp_priority = -1;
62 static void onbsp_destruct(orte_notifier_base_selected_pair_t *obj)
67 OBJ_CLASS_INSTANCE(orte_notifier_base_selected_pair_t,
74 * Function for selecting a set of components from all those that are
77 * It is possible to select a subset of these components for any interface.
78 * The syntax is the following:
79 * [ -mca notifier <list0> ] [ -mca notifier_log <list1> ]
80 * [ -mca notifier_help <list2> ]
81 * [ -mca notifier_log_peer <list3> ]
82 * [ -mca notifier_log_event <list4> ]
84 * . <list0> empty means nothing selected
85 * . <list0> to <list4> = comma separated lists of component names
86 * . <list1> to <list4> may be one of:
87 * . subsets of <list0>
88 * . "none" keyword (means empty)
89 * . 1 of <list1> to <list4> empty means = <list0>
90 * Last point makes it possible to preserve the way it works today
94 * -mca notifier syslog,smtp
95 * --> syslog and smtp are selected for the log, show_help, log_peer and
96 * log_event interfaces.
98 * -mca notifier_log syslog
99 * --> no interface is activated, no component is selected
101 * -mca notifier syslog -mca notifier_help none
102 * -mca notifier_log_peer none
103 * -mca notifier_log_event none
104 * --> only the log interface is activated, with the syslog component
106 * -mca notifier syslog,smtp,hnp -mca notifier_help syslog
107 * -mca notifier_log_peer smtp
108 * -mca notifier_log_event none
109 * --> the log interface is activated, with the syslog, smtp and hnp
111 * the log_help interface is activated, with the syslog component
112 * the log_peer interface is activated, with the smtp component
113 * the log_event interface is not activated
115 int orte_notifier_base_select(void)
117 mca_base_component_list_item_t *cli = NULL;
118 mca_base_component_t *component = NULL;
119 mca_base_module_t *module = NULL;
120 int i, ret, priority, exit_status = ORTE_SUCCESS;
121 opal_list_item_t *item;
122 orte_notifier_base_module_t *nmodule;
124 char **imodules_log, **imodules_help, **imodules_log_peer;
125 char **imodules_log_event = NULL;
129 * Register the framework MCA param and look up include list
131 imodules = orte_notifier_get_include_list("notifier",
132 "Comma-delimisted list of notifier components to use "
133 "(empty = none)", NULL);
134 if (NULL == imodules) {
139 * Also get the include lists for each interface
141 imodules_log = orte_notifier_get_include_list("notifier_log",
142 "Comma-delimisted list of notifier components to use "
143 "for orte_notifier_log (empty = all selected)",
146 imodules_help = orte_notifier_get_include_list("notifier_help",
147 "Comma-delimisted list of notifier components to use "
148 "for orte_notifier_show_help (empty = all selected)",
151 imodules_log_peer = orte_notifier_get_include_list("notifier_log_peer",
152 "Comma-delimisted list of notifier components to "
153 "use for orte_notifier_log_peer (empty = all "
154 "selected)", imodules);
156 #if ORTE_WANT_NOTIFIER_LOG_EVENT
157 imodules_log_event = orte_notifier_get_include_list("notifier_log_event",
158 "Comma-delimisted list of notifier components to "
159 "use for ORTE_NOTIFIER_LOG_EVENT (empty = all "
162 #endif /* ORTE_WANT_NOTIFIER_LOG_EVENT */
164 /* Query all available components and ask if they have a module */
165 for (item = opal_list_get_first(&orte_notifier_base_components_available);
166 opal_list_get_end(&orte_notifier_base_components_available) != item;
167 item = opal_list_get_next(item)) {
168 cli = (mca_base_component_list_item_t *) item;
169 component = (mca_base_component_t *) cli->cli_component;
171 /* If this component is not in the include list, skip it */
172 for (i = 0; NULL != imodules[i]; ++i) {
173 if (0 == strcmp(imodules[i], component->mca_component_name)) {
177 if (NULL == imodules[i]) {
181 /* If there's no query function, skip it */
182 if (NULL == component->mca_query_component) {
183 opal_output_verbose(5, orte_notifier_base_output,
184 "mca:notify:select: Skipping component [%s]. It does not implement a query function",
185 component->mca_component_name );
189 /* Query the component */
190 opal_output_verbose(5, orte_notifier_base_output,
191 "mca:notify:select: Querying component [%s]",
192 component->mca_component_name);
193 ret = component->mca_query_component(&module, &priority);
195 /* If no module was returned, then skip component */
196 if (ORTE_SUCCESS != ret || NULL == module) {
197 opal_output_verbose(5, orte_notifier_base_output,
198 "mca:notify:select: Skipping component [%s]. Query failed to return a module",
199 component->mca_component_name );
203 /* If we got a module, initialize it */
204 nmodule = (orte_notifier_base_module_t*) module;
205 if (NULL != nmodule->init) {
206 /* If the module doesn't want to be used, skip it */
207 if (ORTE_SUCCESS != (ret = nmodule->init()) ) {
208 if (ORTE_ERR_NOT_SUPPORTED != ret &&
209 ORTE_ERR_NOT_IMPLEMENTED != ret) {
214 if (NULL != nmodule->finalize) {
222 * OK, one module has been selected for the notifier framework, and
223 * successfully initialized.
224 * Now we have to include it in the per interface selected modules
227 ret = orte_notifier_add_module(component,
231 &orte_notifier_log_selected_modules);
233 orte_notifier_base_log_selected = orte_notifier_base_log_selected
236 * This variable is set to check if the module is needed by at least
241 ret = orte_notifier_add_module(component,
245 &orte_notifier_help_selected_modules);
246 orte_notifier_base_help_selected = orte_notifier_base_help_selected
248 module_needed = module_needed || ret;
250 ret = orte_notifier_add_module(component,
254 &orte_notifier_log_peer_selected_modules);
255 orte_notifier_base_log_peer_selected =
256 orte_notifier_base_log_peer_selected || ret;
257 module_needed = module_needed || ret;
259 ret = orte_notifier_add_module(component,
263 &orte_notifier_log_event_selected_modules);
264 orte_notifier_base_log_event_selected =
265 orte_notifier_base_log_event_selected || ret;
266 module_needed = module_needed || ret;
269 * If the module is needed by at least one interface:
270 * Unconditionally update the global list that will be used during
271 * the close step. Else unload it.
274 orte_notifier_add_module(component,
278 &orte_notifier_base_selected_modules);
280 if (NULL != nmodule->finalize) {
286 if (orte_notifier_base_log_event_selected) {
288 * This has to be done whatever the selected module. That's why it's
291 orte_notifier_base_events_init();
299 * Register an mca param that represents an include list and build that list.
301 * @param param_name (IN) param name to be registered
302 * @param help_message (IN) help message for that param
303 * @param default_modules (IN) list of module names to be inherited if an
304 * empty include list is provided
305 * @return list of modules names
307 static inline char **orte_notifier_get_include_list(const char *param_name,
308 const char *help_message,
309 char **default_modules)
311 char *include_list = NULL;
314 mca_base_param_reg_string_name(param_name, NULL, help_message,
315 false, false, NULL, &include_list);
316 imodules = opal_argv_split(include_list, ',');
317 if (NULL == imodules) {
319 * Inherit the default list if nothing specified
321 return default_modules;
323 if (!strcmp(include_list, "none")) {
331 * Check if a component name belongs to an include list and add it to the
332 * list of selected modules.
334 * @param component (IN) component to be included
335 * @param module (IN) module to be included
336 * @param priority (IN) module priority
337 * @param include_list (IN) list of module names to go through
338 * @param selected_modules (OUT) list of selected modules to be updated
339 * @return true/false depending on whether the module
340 * has been added or not
342 static bool orte_notifier_add_module(mca_base_component_t *component,
343 orte_notifier_base_module_t *module,
346 opal_list_t *selected_modules)
348 orte_notifier_base_selected_pair_t *pair, *pair2;
350 opal_list_item_t *item;
353 if (NULL == include_list) {
357 module_name = component->mca_component_name;
359 /* If this component is not in the include list, skip it */
360 for (i = 0; NULL != include_list[i]; i++) {
361 if (!strcmp(include_list[i], module_name)) {
365 if (NULL == include_list[i]) {
369 /* Make an item for the list */
370 pair = OBJ_NEW(orte_notifier_base_selected_pair_t);
371 pair->onbsp_component = (orte_notifier_base_component_t*) component;
372 pair->onbsp_module = module;
373 pair->onbsp_priority = priority;
375 /* Put it in the list in priority order */
376 for (item = opal_list_get_first(selected_modules);
377 opal_list_get_end(selected_modules) != item;
378 item = opal_list_get_next(item)) {
379 pair2 = (orte_notifier_base_selected_pair_t*) item;
380 if (priority > pair2->onbsp_priority) {
381 opal_list_insert_pos(selected_modules, item, &(pair->super));
385 if (opal_list_get_end(selected_modules) == item) {
386 opal_list_append(selected_modules, &(pair->super));