root/orte/util/pre_condition_transports.c

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

DEFINITIONS

This source file includes following definitions.
  1. orte_pre_condition_transports_use_rand
  2. orte_pre_condition_transports_print
  3. orte_pre_condition_transports

   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) 2010      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2015      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * Copyright (c) 2016-2018 Intel, Inc.  All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "orte_config.h"
  24 
  25 #include <string.h>
  26 #ifdef HAVE_UNISTD_H
  27 #include <unistd.h>
  28 #endif
  29 #ifdef HAVE_SYS_TYPES_H
  30 #include <sys/types.h>
  31 #endif
  32 #ifdef HAVE_SYS_STAT_H
  33 #include <sys/stat.h>
  34 #endif
  35 #ifdef HAVE_FCNTL_H
  36 #include <fcntl.h>
  37 #endif
  38 #include <time.h>
  39 
  40 #include "opal/mca/base/mca_base_var.h"
  41 #include "opal/util/alfg.h"
  42 #include "opal/util/opal_environ.h"
  43 #include "opal/util/printf.h"
  44 
  45 #include "orte/constants.h"
  46 #include "orte/types.h"
  47 #include "orte/mca/errmgr/errmgr.h"
  48 #include "orte/util/attr.h"
  49 
  50 #include "orte/util/pre_condition_transports.h"
  51 
  52 /* some network transports require a little bit of information to
  53  * "pre-condition" them - i.e., to setup their individual transport
  54  * connections so they can generate their endpoint addresses. This
  55  * function provides a means for doing so. The resulting info is placed
  56  * into the app_context's env array so it will automatically be pushed
  57  * into the environment of every MPI process when launched.
  58  */
  59 
  60 static inline void orte_pre_condition_transports_use_rand(uint64_t* unique_key) {
  61     opal_rng_buff_t rng;
  62     opal_srand(&rng,(unsigned int)time(NULL));
  63     unique_key[0] = opal_rand(&rng);
  64     unique_key[1] = opal_rand(&rng);
  65 }
  66 
  67 char* orte_pre_condition_transports_print(uint64_t *unique_key)
  68 {
  69     unsigned int *int_ptr;
  70     size_t i, j, string_key_len, written_len;
  71     char *string_key = NULL, *format = NULL;
  72 
  73     /* string is two 64 bit numbers printed in hex with a dash between
  74      * and zero padding.
  75      */
  76     string_key_len = (sizeof(uint64_t) * 2) * 2 + strlen("-") + 1;
  77     string_key = (char*) malloc(string_key_len);
  78     if (NULL == string_key) {
  79         return NULL;
  80     }
  81 
  82     string_key[0] = '\0';
  83     written_len = 0;
  84 
  85     /* get a format string based on the length of an unsigned int.  We
  86      * want to have zero padding for sizeof(unsigned int) * 2
  87      * characters -- when printing as a hex number, each byte is
  88      * represented by 2 hex characters.  Format will contain something
  89      * that looks like %08lx, where the number 8 might be a different
  90      * number if the system has a different sized long (8 would be for
  91      * sizeof(int) == 4)).
  92      */
  93     opal_asprintf(&format, "%%0%dx", (int)(sizeof(unsigned int)) * 2);
  94 
  95     /* print the first number */
  96     int_ptr = (unsigned int*) &unique_key[0];
  97     for (i = 0 ; i < sizeof(uint64_t) / sizeof(unsigned int) ; ++i) {
  98         if (0 == int_ptr[i]) {
  99             /* inject some energy */
 100             for (j=0; j < sizeof(unsigned int); j++) {
 101                 int_ptr[i] |= j << j;
 102             }
 103         }
 104         snprintf(string_key + written_len,
 105                  string_key_len - written_len,
 106                  format, int_ptr[i]);
 107         written_len = strlen(string_key);
 108     }
 109 
 110     /* print the middle dash */
 111     snprintf(string_key + written_len, string_key_len - written_len, "-");
 112     written_len = strlen(string_key);
 113 
 114     /* print the second number */
 115     int_ptr = (unsigned int*) &unique_key[1];
 116     for (i = 0 ; i < sizeof(uint64_t) / sizeof(unsigned int) ; ++i) {
 117         if (0 == int_ptr[i]) {
 118             /* inject some energy */
 119             for (j=0; j < sizeof(unsigned int); j++) {
 120                 int_ptr[i] |= j << j;
 121             }
 122         }
 123         snprintf(string_key + written_len,
 124                  string_key_len - written_len,
 125                  format, int_ptr[i]);
 126         written_len = strlen(string_key);
 127     }
 128     free(format);
 129 
 130     return string_key;
 131 }
 132 
 133 
 134 int orte_pre_condition_transports(orte_job_t *jdata, char **key)
 135 {
 136     uint64_t unique_key[2];
 137     int n;
 138     orte_app_context_t *app;
 139     char *string_key, *cs_env;
 140     int fd_rand;
 141     size_t bytes_read;
 142     struct stat buf;
 143 
 144     /* put the number here - or else create an appropriate string. this just needs to
 145      * eventually be a string variable
 146      */
 147     if(0 != stat("/dev/urandom", &buf)) {
 148         /* file doesn't exist! */
 149         orte_pre_condition_transports_use_rand(unique_key);
 150     }
 151 
 152     if(-1 == (fd_rand = open("/dev/urandom", O_RDONLY))) {
 153         orte_pre_condition_transports_use_rand(unique_key);
 154     } else {
 155         bytes_read = read(fd_rand, (char *) unique_key, 16);
 156         if(bytes_read != 16) {
 157             orte_pre_condition_transports_use_rand(unique_key);
 158         }
 159         close(fd_rand);
 160     }
 161 
 162     if (NULL == (string_key = orte_pre_condition_transports_print(unique_key))) {
 163         ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
 164         return ORTE_ERR_OUT_OF_RESOURCE;
 165     }
 166 
 167     /* record it in case this job executes a dynamic spawn */
 168     if (NULL != jdata) {
 169         orte_set_attribute(&jdata->attributes, ORTE_JOB_TRANSPORT_KEY, ORTE_ATTR_LOCAL, string_key, OPAL_STRING);
 170 
 171         if (OPAL_SUCCESS != mca_base_var_env_name ("orte_precondition_transports", &cs_env)) {
 172             ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
 173             free(string_key);
 174             return ORTE_ERR_OUT_OF_RESOURCE;
 175         }
 176 
 177         for (n=0; n < jdata->apps->size; n++) {
 178             if (NULL == (app = (orte_app_context_t*)opal_pointer_array_get_item(jdata->apps, n))) {
 179                 continue;
 180             }
 181             opal_setenv(cs_env, string_key, true, &app->env);
 182         }
 183         free(cs_env);
 184         free(string_key);
 185     } else if (NULL != key) {
 186         *key = string_key;
 187     } else {
 188         free(string_key);
 189     }
 190 
 191     return ORTE_SUCCESS;
 192 }

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