root/ompi/mca/io/base/io_base_delete.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_io_base_delete
  2. avail_io_compare
  3. check_components
  4. check_one_component
  5. query
  6. query_2_0_0
  7. unquery
  8. delete_file

   1 /*
   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
   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) 2008      Sun Microsystems, Inc.  All rights reserved.
  13  * Copyright (c) 2015      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * Copyright (c) 2016-2017 IBM Corporation. All rights reserved.
  16  * Copyright (c) 2008-2018 University of Houston. All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #include "ompi_config.h"
  25 
  26 #include <stdio.h>
  27 #include <string.h>
  28 #include <stdlib.h>
  29 
  30 #include "mpi.h"
  31 #include "opal/class/opal_list.h"
  32 #include "opal/util/argv.h"
  33 #include "opal/util/output.h"
  34 #include "opal/util/info.h"
  35 #include "ompi/mca/mca.h"
  36 #include "opal/mca/base/base.h"
  37 #include "ompi/mca/io/io.h"
  38 #include "ompi/mca/io/base/base.h"
  39 #include "ompi/mca/fs/fs.h"
  40 #include "ompi/mca/fs/base/base.h"
  41 
  42 /*
  43  * Local types
  44  */
  45 struct avail_io_t {
  46     opal_list_item_t super;
  47 
  48     mca_io_base_version_t ai_version;
  49 
  50     int ai_priority;
  51     mca_io_base_components_t ai_component;
  52     struct mca_io_base_delete_t *ai_private_data;
  53 };
  54 typedef struct avail_io_t avail_io_t;
  55 
  56 /*
  57  * Local functions
  58  */
  59 static opal_list_t *check_components(opal_list_t *components,
  60                                      const char *filename, struct opal_info_t *info,
  61                                      char **names, int num_names);
  62 static avail_io_t *check_one_component(const mca_base_component_t *component,
  63                                        const char *filename, struct opal_info_t *info);
  64 
  65 static avail_io_t *query(const mca_base_component_t *component,
  66                          const char *filename, struct opal_info_t *info);
  67 static avail_io_t *query_2_0_0(const mca_io_base_component_2_0_0_t *io_component,
  68                                const char *filename, struct opal_info_t *info);
  69 
  70 static void unquery(avail_io_t *avail, const char *filename, struct opal_info_t *info);
  71 
  72 static int delete_file(avail_io_t *avail, const char *filename, struct opal_info_t *info);
  73 
  74 extern opal_mutex_t ompi_mpi_ompio_bootstrap_mutex;
  75 
  76 
  77 /*
  78  * Stuff for the OBJ interface
  79  */
  80 static OBJ_CLASS_INSTANCE(avail_io_t, opal_list_item_t, NULL, NULL);
  81 
  82 
  83 /*
  84  */
  85 int mca_io_base_delete(const char *filename, struct opal_info_t *info)
  86 {
  87     int err;
  88     opal_list_t *selectable;
  89     opal_list_item_t *item;
  90     avail_io_t *avail, selected;
  91 
  92     /* Announce */
  93 
  94     opal_output_verbose(10, ompi_io_base_framework.framework_output,
  95                         "io:base:delete: deleting file: %s",
  96                         filename);
  97 
  98     /* See if a set of component was requested by the MCA parameter.
  99        Don't check for error. */
 100 
 101     /* Compute the intersection of all of my available components with
 102        the components from all the other processes in this file */
 103 
 104     /* JMS CONTINUE HERE */
 105 
 106     /* See if there were any listed in the MCA parameter; parse them
 107        and check them all */
 108 
 109     err = OMPI_ERROR;
 110     opal_output_verbose(10, ompi_io_base_framework.framework_output,
 111                         "io:base:delete: Checking all available modules");
 112     selectable = check_components(&ompi_io_base_framework.framework_components,
 113                                   filename, info, NULL, 0);
 114 
 115     /* Upon return from the above, the modules list will contain the
 116        list of modules that returned (priority >= 0).  If we have no
 117        io modules available, it's an error */
 118 
 119     if (NULL == selectable) {
 120         /* There's no modules available.  Doh! */
 121         /* show_help */
 122         return OMPI_ERROR;
 123     }
 124     /* Do some kind of collective operation to find a module that
 125        everyone has available */
 126 #if 1
 127     /* For the moment, just take the top module off the list */
 128     /* MSC actually take the buttom */
 129     item = opal_list_remove_last(selectable);
 130     avail = (avail_io_t *) item;
 131     selected = *avail;
 132     OBJ_RELEASE(avail);
 133 #else
 134     /* JMS CONTINUE HERE */
 135 #endif
 136 
 137     /* Everything left in the selectable list is therefore unwanted,
 138        and we call their unquery() method (because they all had
 139        query() invoked, but will never have init() invoked in this
 140        scope). */
 141 
 142     for (item = opal_list_remove_first(selectable); item != NULL;
 143          item = opal_list_remove_first(selectable)) {
 144         avail = (avail_io_t *) item;
 145         unquery(avail, filename, info);
 146         OBJ_RELEASE(item);
 147     }
 148     OBJ_RELEASE(selectable);
 149 
 150     if (!strcmp (selected.ai_component.v2_0_0.io_version.mca_component_name,
 151                  "ompio")) {
 152         int ret;
 153 
 154         opal_mutex_lock(&ompi_mpi_ompio_bootstrap_mutex);
 155         if (OMPI_SUCCESS != (ret = mca_base_framework_open(&ompi_fs_base_framework, 0))) {
 156             opal_mutex_unlock(&ompi_mpi_ompio_bootstrap_mutex);
 157             return err;
 158         }
 159         opal_mutex_unlock(&ompi_mpi_ompio_bootstrap_mutex);
 160 
 161         if (OMPI_SUCCESS !=
 162             (ret = mca_fs_base_find_available(OPAL_ENABLE_PROGRESS_THREADS, 1))) {
 163             return err;
 164         }
 165     }
 166 
 167     
 168     /* Finally -- delete the file with the selected component */
 169     if (OMPI_SUCCESS != (err = delete_file(&selected, filename, info))) {
 170         return err;
 171     }
 172 
 173     /* Announce the winner */
 174 
 175     opal_output_verbose(10, ompi_io_base_framework.framework_output,
 176                         "io:base:delete: Selected io component %s",
 177                         selected.ai_component.v2_0_0.io_version.mca_component_name);
 178 
 179     return OMPI_SUCCESS;
 180 }
 181 
 182 
 183 static int avail_io_compare (opal_list_item_t **itema,
 184                              opal_list_item_t **itemb)
 185 {
 186     const avail_io_t *availa = (const avail_io_t *) *itema;
 187     const avail_io_t *availb = (const avail_io_t *) *itemb;
 188 
 189     /* highest component last */
 190     if (availa->ai_priority > availb->ai_priority) {
 191         return 1;
 192     } else if (availa->ai_priority < availb->ai_priority) {
 193         return -1;
 194     } else {
 195         return 0;
 196     }
 197 }
 198 
 199 /*
 200  * For each module in the list, if it is in the list of names (or the
 201  * list of names is NULL), then check and see if it wants to run, and
 202  * do the resulting priority comparison.  Make a list of components to
 203  * be only those who returned that they want to run, and put them in
 204  * priority order.
 205  */
 206 static opal_list_t *check_components(opal_list_t *components,
 207                                      const char *filename, struct opal_info_t *info,
 208                                      char **names, int num_names)
 209 {
 210     int i;
 211     const mca_base_component_t *component;
 212     mca_base_component_list_item_t *cli;
 213     bool want_to_check;
 214     opal_list_t *selectable;
 215     avail_io_t *avail;
 216 
 217     /* Make a list of the components that query successfully */
 218 
 219     selectable = OBJ_NEW(opal_list_t);
 220 
 221     /* Scan through the list of components.  This nested loop is
 222        O(N^2), but we should never have too many components and/or
 223        names, so this *hopefully* shouldn't matter... */
 224 
 225     OPAL_LIST_FOREACH(cli, components, mca_base_component_list_item_t) {
 226         component = cli->cli_component;
 227 
 228         /* If we have a list of names, scan through it */
 229 
 230         if (0 == num_names) {
 231             want_to_check = true;
 232         } else {
 233             want_to_check = false;
 234             for (i = 0; i < num_names; ++i) {
 235                 if (0 == strcmp(names[i], component->mca_component_name)) {
 236                     want_to_check = true;
 237                 }
 238             }
 239         }
 240 
 241         /* If we determined that we want to check this component, then
 242            do so */
 243 
 244         if (want_to_check) {
 245             avail = check_one_component(component, filename, info);
 246             if (NULL != avail) {
 247 
 248                 /* Put this item on the list in priority order
 249                    (highest priority first).  Should it go first? */
 250                 /* MSC actually put it Lowest priority first */
 251                 /* NTH sort this out later */
 252                 opal_list_append(selectable, (opal_list_item_t*)avail);
 253             }
 254         }
 255     }
 256 
 257     /* If we didn't find any available components, return an error */
 258 
 259     if (0 == opal_list_get_size(selectable)) {
 260         OBJ_RELEASE(selectable);
 261         return NULL;
 262     }
 263 
 264     opal_list_sort(selectable, avail_io_compare);
 265 
 266     /* All done */
 267 
 268     return selectable;
 269 }
 270 
 271 
 272 /*
 273  * Check a single component
 274  */
 275 static avail_io_t *check_one_component(const mca_base_component_t *component,
 276                                        const char *filename, struct opal_info_t *info)
 277 {
 278     avail_io_t *avail;
 279 
 280     avail = query(component, filename, info);
 281     if (NULL != avail) {
 282         avail->ai_priority = (avail->ai_priority < 100) ?
 283             avail->ai_priority : 100;
 284         avail->ai_priority = (avail->ai_priority < 0) ?
 285             0 : avail->ai_priority;
 286         opal_output_verbose(10, ompi_io_base_framework.framework_output,
 287                             "io:base:delete: component available: %s, priority: %d",
 288                             component->mca_component_name,
 289                             avail->ai_priority);
 290     } else {
 291         opal_output_verbose(10, ompi_io_base_framework.framework_output,
 292                             "io:base:delete: component not available: %s",
 293                             component->mca_component_name);
 294     }
 295 
 296     return avail;
 297 }
 298 
 299 
 300 /**************************************************************************
 301  * Query functions
 302  **************************************************************************/
 303 
 304 /*
 305  * Take any version of a io module, query it, and return the right
 306  * module struct
 307  */
 308 static avail_io_t *query(const mca_base_component_t *component,
 309                          const char *filename, struct opal_info_t *info)
 310 {
 311     const mca_io_base_component_2_0_0_t *ioc_200;
 312 
 313     /* io v2.0.0 */
 314 
 315     if (MCA_BASE_VERSION_MAJOR == component->mca_major_version &&
 316         MCA_BASE_VERSION_MINOR == component->mca_minor_version &&
 317         MCA_BASE_VERSION_RELEASE == component->mca_release_version) {
 318         ioc_200 = (mca_io_base_component_2_0_0_t *) component;
 319 
 320         return query_2_0_0(ioc_200, filename, info);
 321     }
 322 
 323     /* Unknown io API version -- return error */
 324 
 325     return NULL;
 326 }
 327 
 328 
 329 static avail_io_t *query_2_0_0(const mca_io_base_component_2_0_0_t *component,
 330                                const char *filename, struct opal_info_t *info)
 331 {
 332     bool usable;
 333     int priority, ret;
 334     avail_io_t *avail;
 335     struct mca_io_base_delete_t *private_data;
 336 
 337     /* Query v2.0.0 */
 338 
 339     avail = NULL;
 340     private_data = NULL;
 341     usable = false;
 342     ret = component->io_delete_query(filename, info, &private_data, &usable,
 343                                      &priority);
 344     if (OMPI_SUCCESS == ret && usable) {
 345         avail = OBJ_NEW(avail_io_t);
 346         avail->ai_version = MCA_IO_BASE_V_2_0_0;
 347         avail->ai_priority = priority;
 348         avail->ai_component.v2_0_0 = *component;
 349         avail->ai_private_data = private_data;
 350     }
 351 
 352     return avail;
 353 }
 354 
 355 
 356 /**************************************************************************
 357  * Unquery functions
 358  **************************************************************************/
 359 
 360 static void unquery(avail_io_t *avail, const char *filename, struct opal_info_t *info)
 361 {
 362     const mca_io_base_component_2_0_0_t *ioc_200;
 363 
 364     switch(avail->ai_version) {
 365     case MCA_IO_BASE_V_2_0_0:
 366         ioc_200 = &(avail->ai_component.v2_0_0);
 367         if (NULL != ioc_200->io_delete_unquery) {
 368             ioc_200->io_delete_unquery(filename, info, avail->ai_private_data);
 369         }
 370         break;
 371 
 372     default:
 373         break;
 374     }
 375 }
 376 
 377 
 378 /**************************************************************************
 379  * File delete functions
 380  **************************************************************************/
 381 
 382 /*
 383  * Invoke the component's delete function
 384  */
 385 static int delete_file(avail_io_t *avail, const char *filename, struct opal_info_t *info)
 386 {
 387     const mca_io_base_component_2_0_0_t *ioc_200;
 388 
 389     switch(avail->ai_version) {
 390     case MCA_IO_BASE_V_2_0_0:
 391         ioc_200 = &(avail->ai_component.v2_0_0);
 392         return ioc_200->io_delete_select(filename, info,
 393                                          avail->ai_private_data);
 394         break;
 395 
 396     default:
 397         return OMPI_ERROR;
 398         break;
 399     }
 400 
 401     /* No way to reach here */
 402 }

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