root/opal/mca/pmix/pmix4x/pmix/src/mca/plog/base/plog_base_select.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmix_plog_base_select

   1 /*
   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
   7  *                         reserved.
   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) 2016-2018 Intel, Inc. All rights reserved.
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 
  20 #include <src/include/pmix_config.h>
  21 #include <pmix_common.h>
  22 
  23 #include <string.h>
  24 
  25 #include "src/mca/mca.h"
  26 #include "src/mca/base/base.h"
  27 #include "src/util/show_help.h"
  28 
  29 #include "src/mca/plog/base/base.h"
  30 
  31 static bool selected = false;
  32 
  33 /* Function for selecting a prioritized array of components
  34  * from all those that are available. */
  35 int pmix_plog_base_select(void)
  36 {
  37     pmix_mca_base_component_list_item_t *cli = NULL;
  38     pmix_mca_base_component_t *component = NULL;
  39     pmix_mca_base_module_t *module = NULL;
  40     pmix_plog_module_t *nmodule;
  41     pmix_plog_base_active_module_t *newmodule, *mod, *default_mod = NULL;
  42     int rc, priority, n;
  43     bool inserted, default_added, reqd;
  44     pmix_list_t actives;
  45     char *ptr;
  46     size_t len;
  47 
  48     if (selected) {
  49         /* ensure we don't do this twice */
  50         return PMIX_SUCCESS;
  51     }
  52     selected = true;
  53 
  54     PMIX_CONSTRUCT(&actives, pmix_list_t);
  55 
  56     /* Query all available components and ask if they have a module */
  57     PMIX_LIST_FOREACH(cli, &pmix_plog_base_framework.framework_components, pmix_mca_base_component_list_item_t) {
  58         component = (pmix_mca_base_component_t *) cli->cli_component;
  59 
  60         pmix_output_verbose(5, pmix_plog_base_framework.framework_output,
  61                             "mca:plog:select: checking available component %s", component->pmix_mca_component_name);
  62 
  63         /* If there's no query function, skip it */
  64         if (NULL == component->pmix_mca_query_component) {
  65             pmix_output_verbose(5, pmix_plog_base_framework.framework_output,
  66                                 "mca:plog:select: Skipping component [%s]. It does not implement a query function",
  67                                 component->pmix_mca_component_name );
  68             continue;
  69         }
  70 
  71         /* Query the component */
  72         pmix_output_verbose(5, pmix_plog_base_framework.framework_output,
  73                             "mca:plog:select: Querying component [%s]",
  74                             component->pmix_mca_component_name);
  75         rc = component->pmix_mca_query_component(&module, &priority);
  76 
  77         /* If no module was returned, then skip component */
  78         if (PMIX_SUCCESS != rc || NULL == module) {
  79             pmix_output_verbose(5, pmix_plog_base_framework.framework_output,
  80                                 "mca:plog:select: Skipping component [%s]. Query failed to return a module",
  81                                 component->pmix_mca_component_name );
  82             continue;
  83         }
  84 
  85         /* If we got a module, keep it */
  86         nmodule = (pmix_plog_module_t*) module;
  87         /* let it initialize */
  88         if (NULL != nmodule->init && PMIX_SUCCESS != nmodule->init()) {
  89             continue;
  90         }
  91         /* add to the list of selected modules */
  92         newmodule = PMIX_NEW(pmix_plog_base_active_module_t);
  93         newmodule->pri = priority;
  94         newmodule->module = nmodule;
  95         newmodule->component = (pmix_plog_base_component_t*)cli->cli_component;
  96 
  97         /* maintain priority order */
  98         inserted = false;
  99         PMIX_LIST_FOREACH(mod, &actives, pmix_plog_base_active_module_t) {
 100             if (priority > mod->pri) {
 101                 pmix_list_insert_pos(&actives, (pmix_list_item_t*)mod, &newmodule->super);
 102                 inserted = true;
 103                 break;
 104             }
 105         }
 106         if (!inserted) {
 107             /* must be lowest priority - add to end */
 108             pmix_list_append(&actives, &newmodule->super);
 109         }
 110 
 111         /* if this is the default module, track it */
 112         if (0 == strcmp(newmodule->module->name, "default")) {
 113             default_mod = newmodule;
 114         }
 115     }
 116 
 117     /* if they gave us a desired ordering, then impose it here */
 118     if (NULL != pmix_plog_globals.channels) {
 119         default_added = false;
 120         for (n=0; NULL != pmix_plog_globals.channels[n]; n++) {
 121             len = strlen(pmix_plog_globals.channels[n]);
 122             /* check for the "req" modifier */
 123             reqd = false;
 124             ptr = strrchr(pmix_plog_globals.channels[n], ':');
 125             if (NULL != ptr) {
 126                 /* get the length of the remaining string so we
 127                  * can constrain our comparison of the channel
 128                  * name itself */
 129                 len = len - strlen(ptr);
 130                 /* move over the ':' */
 131                 ++ptr;
 132                 /* we accept anything that starts with "req" */
 133                 if (0 == strncasecmp(ptr, "req", 3)) {
 134                     reqd = true;
 135                 }
 136             }
 137             /* now search for this channel in our list of actives */
 138             inserted = false;
 139             PMIX_LIST_FOREACH(mod, &actives, pmix_plog_base_active_module_t) {
 140                 if (0 == strncasecmp(pmix_plog_globals.channels[n], mod->module->name, len)) {
 141                     pmix_list_remove_item(&actives, &mod->super);
 142                     pmix_pointer_array_add(&pmix_plog_globals.actives, mod);
 143                     mod->reqd = reqd;
 144                     inserted = true;
 145                     break;
 146                 }
 147             }
 148             if (!inserted) {
 149                 /* we didn't find a supporting module - this
 150                  * still might be okay because it could be something
 151                  * the RM itself supports, so just insert the default
 152                  * module here if it hasn't already been inserted */
 153                 if (!default_added) {
 154                     /* if the default module isn't available and this
 155                      * channel isn't optional, then there is nothing
 156                      * we can do except report an error */
 157                     if (NULL == default_mod && reqd) {
 158                         pmix_show_help("help-pmix-plog.txt", "reqd-not-found",
 159                                        true, pmix_plog_globals.channels[n]);
 160                         PMIX_LIST_DESTRUCT(&actives);
 161                         return PMIX_ERR_NOT_FOUND;
 162                     } else if (NULL != default_mod) {
 163                         pmix_pointer_array_add(&pmix_plog_globals.actives, default_mod);
 164                         default_added = true;
 165                         default_mod->reqd = reqd;
 166                     }
 167                 } else if (reqd) {
 168                     /* if we already added it, we still have to check the
 169                      * reqd status - if any citation requires that the
 170                      * default be used, then we set it, but be sure we
 171                      * don't overwrite it with a "not required" if it
 172                      * was already set as "required" */
 173                     default_mod->reqd = reqd;
 174                 }
 175             }
 176         }
 177         /* if there are any modules left over, we need to discard them */
 178         PMIX_LIST_DESTRUCT(&actives);
 179     } else {
 180         /* insert the modules into the global array in priority order */
 181         while (NULL != (mod = (pmix_plog_base_active_module_t*)pmix_list_remove_first(&actives))) {
 182             pmix_pointer_array_add(&pmix_plog_globals.actives, mod);
 183         }
 184         PMIX_DESTRUCT(&actives);
 185     }
 186 
 187     if (4 < pmix_output_get_verbosity(pmix_plog_base_framework.framework_output)) {
 188         pmix_output(0, "Final plog order");
 189         /* show the prioritized order */
 190         for (n=0; n < pmix_plog_globals.actives.size; n++) {
 191             if (NULL != (mod = (pmix_plog_base_active_module_t*)pmix_pointer_array_get_item(&pmix_plog_globals.actives, n))) {
 192                 pmix_output(0, "\tplog[%d]: %s", n, mod->component->base.pmix_mca_component_name);
 193             }
 194         }
 195     }
 196 
 197 
 198     return PMIX_SUCCESS;;
 199 }

/* [<][>][^][v][top][bottom][index][help] */