root/opal/mca/base/mca_base_component_find.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_base_component_find
  2. mca_base_component_find_finalize
  3. mca_base_components_filter
  4. find_dyn_components
  5. use_component
  6. component_find_check
  7. mca_base_component_parse_requested

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2007 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2008-2015 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2008      Sun Microsystems, Inc.  All rights reserved.
  15  * Copyright (c) 2015      Research Organization for Information Science
  16  *                         and Technology (RIST). All rights reserved.
  17  * Copyright (c) 2014-2015 Los Alamos National Security, LLC. All rights
  18  *                         reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 #include "opal_config.h"
  27 
  28 #include <stdio.h>
  29 #include <string.h>
  30 #include <ctype.h>
  31 #include <stdlib.h>
  32 #ifdef HAVE_SYS_TYPES_H
  33 #include <sys/types.h>
  34 #endif
  35 #ifdef HAVE_SYS_STAT_H
  36 #include <sys/stat.h>
  37 #endif
  38 #ifdef HAVE_UNISTD_H
  39 #include <unistd.h>
  40 #endif
  41 #ifdef HAVE_SYS_PARAM_H
  42 #include <sys/param.h>
  43 #endif
  44 #ifdef HAVE_NETDB_H
  45 #include <netdb.h>
  46 #endif
  47 
  48 #include "opal/mca/installdirs/installdirs.h"
  49 #include "opal/util/opal_environ.h"
  50 #include "opal/util/output.h"
  51 #include "opal/util/argv.h"
  52 #include "opal/util/show_help.h"
  53 #include "opal/class/opal_list.h"
  54 #include "opal/mca/mca.h"
  55 #include "opal/mca/base/base.h"
  56 #include "opal/mca/base/mca_base_component_repository.h"
  57 #include "opal/constants.h"
  58 #include "opal/mca/dl/base/base.h"
  59 
  60 #if OPAL_HAVE_DL_SUPPORT
  61 /*
  62  * Private functions
  63  */
  64 static void find_dyn_components(const char *path, mca_base_framework_t *framework,
  65                                 const char **names, bool include_mode);
  66 
  67 #endif /* OPAL_HAVE_DL_SUPPORT */
  68 
  69 static int component_find_check (mca_base_framework_t *framework, char **requested_component_names);
  70 
  71 /*
  72  * Dummy structure for casting for open_only logic
  73  */
  74 struct mca_base_open_only_dummy_component_t {
  75     /** MCA base component */
  76     mca_base_component_t version;
  77     /** MCA base data */
  78     mca_base_component_data_t data;
  79 };
  80 typedef struct mca_base_open_only_dummy_component_t mca_base_open_only_dummy_component_t;
  81 
  82 static char negate[] = "^";
  83 
  84 static bool use_component(const bool include_mode,
  85                           const char **requested_component_names,
  86                           const char *component_name);
  87 
  88 
  89 /*
  90  * Function to find as many components of a given type as possible.  This
  91  * includes statically-linked in components as well as opening up a
  92  * directory and looking for shared-library MCA components of the
  93  * appropriate type (load them if available).
  94  *
  95  * Return one consolidated array of (mca_base_component_t*) pointing to all
  96  * available components.
  97  */
  98 int mca_base_component_find (const char *directory, mca_base_framework_t *framework,
  99                              bool ignore_requested, bool open_dso_components)
 100 {
 101     const mca_base_component_t **static_components = framework->framework_static_components;
 102     char **requested_component_names = NULL;
 103     mca_base_component_list_item_t *cli;
 104     bool include_mode = true;
 105     int ret;
 106 
 107     if (!ignore_requested) {
 108         ret = mca_base_component_parse_requested (framework->framework_selection, &include_mode,
 109                                                   &requested_component_names);
 110         if (OPAL_SUCCESS != ret) {
 111             return ret;
 112         }
 113     }
 114 
 115     /* Find all the components that were statically linked in */
 116     if (static_components) {
 117         for (int i = 0 ; NULL != static_components[i]; ++i) {
 118             if ( use_component(include_mode,
 119                                (const char**)requested_component_names,
 120                                static_components[i]->mca_component_name) ) {
 121                 cli = OBJ_NEW(mca_base_component_list_item_t);
 122                 if (NULL == cli) {
 123                     ret = OPAL_ERR_OUT_OF_RESOURCE;
 124                     goto component_find_out;
 125                 }
 126                 cli->cli_component = static_components[i];
 127                 opal_list_append(&framework->framework_components, (opal_list_item_t *) cli);
 128             }
 129         }
 130     }
 131 
 132 #if OPAL_HAVE_DL_SUPPORT
 133     /* Find any available dynamic components in the specified directory */
 134     if (open_dso_components && !mca_base_component_disable_dlopen) {
 135         find_dyn_components(directory, framework, (const char**)requested_component_names,
 136                             include_mode);
 137     } else {
 138         opal_output_verbose (MCA_BASE_VERBOSE_INFO, 0,
 139                             "mca: base: component_find: dso loading for %s MCA components disabled",
 140                             framework->framework_name);
 141     }
 142 #endif
 143 
 144     if (include_mode) {
 145         ret = component_find_check (framework, requested_component_names);
 146     } else {
 147         ret = OPAL_SUCCESS;
 148     }
 149 
 150 component_find_out:
 151 
 152     if (NULL != requested_component_names) {
 153         opal_argv_free(requested_component_names);
 154     }
 155 
 156     /* All done */
 157 
 158     return ret;
 159 }
 160 
 161 int mca_base_component_find_finalize(void)
 162 {
 163     return OPAL_SUCCESS;
 164 }
 165 
 166 int mca_base_components_filter (mca_base_framework_t *framework, uint32_t filter_flags)
 167 {
 168     opal_list_t *components = &framework->framework_components;
 169     int output_id = framework->framework_output;
 170     mca_base_component_list_item_t *cli, *next;
 171     char **requested_component_names = NULL;
 172     bool include_mode, can_use;
 173     int ret;
 174 
 175     assert (NULL != components);
 176 
 177     if (0 == filter_flags && NULL == framework->framework_selection) {
 178         return OPAL_SUCCESS;
 179     }
 180 
 181     ret = mca_base_component_parse_requested (framework->framework_selection, &include_mode,
 182                                               &requested_component_names);
 183     if (OPAL_SUCCESS != ret) {
 184         return ret;
 185     }
 186 
 187     OPAL_LIST_FOREACH_SAFE(cli, next, components, mca_base_component_list_item_t) {
 188         const mca_base_component_t *component = cli->cli_component;
 189         mca_base_open_only_dummy_component_t *dummy =
 190             (mca_base_open_only_dummy_component_t *) cli->cli_component;
 191 
 192         can_use = use_component (include_mode, (const char **) requested_component_names,
 193                                  cli->cli_component->mca_component_name);
 194 
 195         if (!can_use || (filter_flags & dummy->data.param_field) != filter_flags) {
 196             if (can_use && (filter_flags & MCA_BASE_METADATA_PARAM_CHECKPOINT) &&
 197                 !(MCA_BASE_METADATA_PARAM_CHECKPOINT & dummy->data.param_field)) {
 198                 opal_output_verbose (MCA_BASE_VERBOSE_COMPONENT, output_id,
 199                                      "mca: base: components_filter: "
 200                                      "(%s) Component %s is *NOT* Checkpointable - Disabled",
 201                                      component->reserved,
 202                                      component->mca_component_name);
 203             }
 204 
 205             opal_list_remove_item (components, &cli->super);
 206 
 207             mca_base_component_unload (component, output_id);
 208 
 209             OBJ_RELEASE(cli);
 210         } else if (filter_flags & MCA_BASE_METADATA_PARAM_CHECKPOINT) {
 211             opal_output_verbose (MCA_BASE_VERBOSE_COMPONENT, output_id,
 212                                  "mca: base: components_filter: "
 213                                  "(%s) Component %s is Checkpointable",
 214                                  component->reserved,
 215                                  component->mca_component_name);
 216         }
 217     }
 218 
 219     if (include_mode) {
 220         ret = component_find_check (framework, requested_component_names);
 221     } else {
 222         ret = OPAL_SUCCESS;
 223     }
 224 
 225     if (NULL != requested_component_names) {
 226         opal_argv_free (requested_component_names);
 227     }
 228 
 229     return ret;
 230 }
 231 
 232 #if OPAL_HAVE_DL_SUPPORT
 233 
 234 /*
 235  * Open up all directories in a given path and search for components of
 236  * the specified type (and possibly of a given name).
 237  *
 238  * Note that we use our own path iteration functionality because we
 239  * need to look at companion .ompi_info files in the same directory as
 240  * the library to generate dependencies, etc.
 241  */
 242 static void find_dyn_components(const char *path, mca_base_framework_t *framework,
 243                                 const char **names, bool include_mode)
 244 {
 245     mca_base_component_repository_item_t *ri;
 246     opal_list_t *dy_components;
 247     int ret;
 248 
 249     if (NULL != path) {
 250         ret = mca_base_component_repository_add (path);
 251         if (OPAL_SUCCESS != ret) {
 252             return;
 253         }
 254     }
 255 
 256     ret = mca_base_component_repository_get_components (framework, &dy_components);
 257     if (OPAL_SUCCESS != ret) {
 258         return;
 259     }
 260 
 261     /* Iterate through the repository and find components that can be included */
 262     OPAL_LIST_FOREACH(ri, dy_components, mca_base_component_repository_item_t) {
 263         if (use_component(include_mode, names, ri->ri_name)) {
 264             mca_base_component_repository_open (framework, ri);
 265         }
 266     }
 267 }
 268 
 269 #endif /* OPAL_HAVE_DL_SUPPORT */
 270 
 271 static bool use_component(const bool include_mode,
 272                           const char **requested_component_names,
 273                           const char *component_name)
 274 {
 275     bool found = false;
 276     const char **req_comp_name = requested_component_names;
 277 
 278     /*
 279      * If no selection is specified then we use all components
 280      * we can find.
 281      */
 282     if (NULL == req_comp_name) {
 283         return true;
 284     }
 285 
 286     while ( *req_comp_name != NULL ) {
 287         if ( strcmp(component_name, *req_comp_name) == 0 ) {
 288             found = true;
 289             break;
 290         }
 291         req_comp_name++;
 292     }
 293 
 294     /*
 295      * include_mode  found |   use
 296      * --------------------+------
 297      *            0      0 |  true
 298      *            0      1 | false
 299      *            1      0 | false
 300      *            1      1 |  true
 301      *
 302      * -> inverted xor
 303      * As xor is a binary operator let's implement it manually before
 304      * a compiler screws it up.
 305      */
 306 
 307     return (include_mode && found) || !(include_mode || found);
 308 }
 309 
 310 /* Ensure that *all* requested components exist.  Print a warning
 311    and abort if they do not. */
 312 static int component_find_check (mca_base_framework_t *framework, char **requested_component_names)
 313 {
 314     opal_list_t *components = &framework->framework_components;
 315     mca_base_component_list_item_t *cli;
 316 
 317     if (NULL == requested_component_names) {
 318         return OPAL_SUCCESS;
 319     }
 320 
 321     for (int i = 0; NULL != requested_component_names[i]; ++i) {
 322         bool found = false;
 323 
 324         OPAL_LIST_FOREACH(cli, components, mca_base_component_list_item_t) {
 325             if (0 == strcmp(requested_component_names[i],
 326                             cli->cli_component->mca_component_name)) {
 327                 found = true;
 328                 break;
 329             }
 330         }
 331 
 332         if (!found) {
 333             char h[OPAL_MAXHOSTNAMELEN];
 334             gethostname(h, sizeof(h));
 335             opal_show_help("help-mca-base.txt",
 336                            "find-available:not-valid", true,
 337                            h, framework->framework_name, requested_component_names[i]);
 338             return OPAL_ERR_NOT_FOUND;
 339         }
 340     }
 341 
 342     return OPAL_SUCCESS;
 343 }
 344 
 345 int mca_base_component_parse_requested (const char *requested, bool *include_mode,
 346                                         char ***requested_component_names)
 347 {
 348     const char *requested_orig = requested;
 349 
 350     *requested_component_names = NULL;
 351     *include_mode = true;
 352 
 353     /* See if the user requested anything */
 354     if (NULL == requested || 0 == strlen (requested)) {
 355         return OPAL_SUCCESS;
 356     }
 357 
 358     /* Are we including or excluding?  We only allow the negate
 359        character to be the *first* character of the value (but be nice
 360        and allow any number of negate characters in the beginning). */
 361     *include_mode = requested[0] != negate[0];
 362 
 363     /* skip over all negate symbols at the beginning */
 364     requested += strspn (requested, negate);
 365 
 366     /* Double check to ensure that the user did not specify the negate
 367        character anywhere else in the value. */
 368     if (NULL != strstr (requested, negate)) {
 369         opal_show_help("help-mca-base.txt",
 370                        "framework-param:too-many-negates",
 371                        true, requested_orig);
 372         return OPAL_ERROR;
 373     }
 374 
 375     /* Split up the value into individual component names */
 376     *requested_component_names = opal_argv_split(requested, ',');
 377 
 378     /* All done */
 379     return OPAL_SUCCESS;
 380 }

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