root/opal/mca/btl/usnic/btl_usnic_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_btl_usnic_exit
  2. opal_btl_usnic_util_abort
  3. opal_btl_usnic_dump_hex
  4. opal_btl_usnic_snprintf_ipv4_addr
  5. opal_btl_usnic_snprintf_bool_array
  6. opal_btl_usnic_convertor_pack_peek

   1 /*
   2  * Copyright (c) 2013-2019 Cisco Systems, Inc.  All rights reserved
   3  * $COPYRIGHT$
   4  *
   5  * Additional copyrights may follow
   6  *
   7  * $HEADER$
   8  */
   9 
  10 #include "opal_config.h"
  11 
  12 #include <stdio.h>
  13 #include <unistd.h>
  14 
  15 #include "opal/util/show_help.h"
  16 #include "opal/constants.h"
  17 #include "opal/util/if.h"
  18 
  19 #include "btl_usnic_module.h"
  20 #include "btl_usnic_util.h"
  21 
  22 
  23 // The following comment tells Coverity that this function does not return.
  24 // See https://scan.coverity.com/tune.
  25 
  26 /* coverity[+kill] */
  27 void opal_btl_usnic_exit(opal_btl_usnic_module_t *module)
  28 {
  29     if (NULL == module) {
  30         /* Find the first module with an error callback */
  31         for (int i = 0; i < mca_btl_usnic_component.num_modules; ++i) {
  32             if (NULL != mca_btl_usnic_component.usnic_active_modules &&
  33                 NULL != mca_btl_usnic_component.usnic_active_modules[i] &&
  34                 NULL != mca_btl_usnic_component.usnic_active_modules[i]->pml_error_callback) {
  35                 module = mca_btl_usnic_component.usnic_active_modules[i];
  36                 break;
  37             }
  38         }
  39         /* If we didn't find a PML error callback, just exit. */
  40         if (NULL == module) {
  41             fprintf(stderr, "*** The Open MPI usnic BTL is aborting the MPI job (via exit(3)).\n");
  42             fflush(stderr);
  43             exit(1);
  44         }
  45     }
  46 
  47     /* After discussion with George, we decided that it was safe to
  48        cast away the const from opal_proc_local_get() -- the error
  49        function needs to be smart enough to not take certain actions
  50        if the passed proc is yourself (e.g., don't call del_procs() on
  51        yourself). */
  52     if (NULL != module->pml_error_callback) {
  53         module->pml_error_callback(&module->super,
  54                                    MCA_BTL_ERROR_FLAGS_FATAL,
  55                                    (opal_proc_t*) opal_proc_local_get(),
  56                                    "The usnic BTL is aborting the MPI job (via PML error callback).");
  57     }
  58 
  59     /* If the PML error callback returns (or if there wasn't one),
  60        just exit.  Shrug. */
  61     exit(1);
  62 }
  63 
  64 
  65 /*
  66  * Simple utility in a .c file, mainly so that inline functions in .h
  67  * files don't need to include the show_help header file.
  68  *
  69  * The following comment tells Coverity that this function does not
  70  * return.  See https://scan.coverity.com/tune.  Technically, we
  71  * shouldn't need this, because opal_btl_usnic_exit() has the same
  72  * annotation, but let's just help Coverity out.
  73  */
  74 
  75 /* coverity[+kill] */
  76 void opal_btl_usnic_util_abort(const char *msg, const char *file, int line)
  77 {
  78     opal_show_help("help-mpi-btl-usnic.txt", "internal error after init",
  79                    true,
  80                    opal_process_info.nodename,
  81                    file, line, msg);
  82 
  83     opal_btl_usnic_exit(NULL);
  84     /* Never returns */
  85 }
  86 
  87 
  88 void
  89 opal_btl_usnic_dump_hex(int verbose_level, int output_id,
  90                         void *vaddr, int len)
  91 {
  92     char buf[128];
  93     size_t bufspace;
  94     int i, ret;
  95     char *p;
  96     uint32_t sum=0;
  97     uint8_t *addr;
  98 
  99     addr = vaddr;
 100     p = buf;
 101     memset(buf, 0, sizeof(buf));
 102     bufspace = sizeof(buf) - 1;
 103 
 104     for (i=0; i<len; ++i) {
 105         ret = snprintf(p, bufspace, "%02x ", addr[i]);
 106         p += ret;
 107         bufspace -= ret;
 108 
 109         sum += addr[i];
 110         if ((i&15) == 15) {
 111             opal_output_verbose(verbose_level, output_id,
 112                                 "%4x: %s\n", i&~15, buf);
 113 
 114             p = buf;
 115             memset(buf, 0, sizeof(buf));
 116             bufspace = sizeof(buf) - 1;
 117         }
 118     }
 119     if ((i&15) != 0) {
 120         opal_output_verbose(verbose_level, output_id,
 121                             "%4x: %s\n", i&~15, buf);
 122     }
 123     /*opal_output_verbose(verbose_level, output_id, "buffer sum = %x\n", sum); */
 124 }
 125 
 126 
 127 /*
 128  * Trivial wrapper around snprintf'ing an IPv4 address, with or
 129  * without a CIDR mask (we don't usually carry around addresses in
 130  * struct sockaddr form, so this wrapper is marginally easier than
 131  * using inet_ntop()).
 132  */
 133 void opal_btl_usnic_snprintf_ipv4_addr(char *out, size_t maxlen,
 134                                        uint32_t addr_be, uint32_t netmask_be)
 135 {
 136     int prefixlen;
 137     uint32_t netmask = ntohl(netmask_be);
 138     uint32_t addr = ntohl(addr_be);
 139     uint8_t *p = (uint8_t*) &addr;
 140 
 141     if (netmask != 0) {
 142         prefixlen = 33 - ffs(netmask);
 143         snprintf(out, maxlen, "%u.%u.%u.%u/%u",
 144                  p[3],
 145                  p[2],
 146                  p[1],
 147                  p[0],
 148                  prefixlen);
 149     } else {
 150         snprintf(out, maxlen, "%u.%u.%u.%u",
 151                  p[3],
 152                  p[2],
 153                  p[1],
 154                  p[0]);
 155     }
 156 }
 157 
 158 
 159 /* Pretty-print the given boolean array as a hexadecimal string.  slen should
 160  * include space for any null terminator. */
 161 void opal_btl_usnic_snprintf_bool_array(char *s, size_t slen, bool a[],
 162                                         size_t alen)
 163 {
 164     size_t i = 0;
 165     size_t j = 0;
 166 
 167     /* could accommodate other cases, but not needed right now */
 168     assert(slen % 4 == 0);
 169 
 170     /* compute one nybble at a time */
 171     while (i < alen && (j < slen - 1)) {
 172         unsigned char tmp = 0;
 173 
 174         /* first bool is the leftmost (most significant) bit of the nybble */
 175         tmp |= !!a[i+0] << 3;
 176         tmp |= !!a[i+1] << 2;
 177         tmp |= !!a[i+2] << 1;
 178         tmp |= !!a[i+3] << 0;
 179         tmp += '0';
 180         s[j] = tmp;
 181 
 182         ++j;
 183         i += 4;
 184     }
 185 
 186     s[j++] = '\0';
 187     assert(i <= alen);
 188     assert(j <= slen);
 189 }
 190 
 191 /* Return the largest size data size that can be packed into max_len using the
 192  * given convertor.  For example, a 1000 byte max_len buffer may only be able
 193  * to hold 998 bytes if an indivisible convertor element straddles the 1000
 194  * byte boundary.
 195  *
 196  * This routine internally clones the convertor and does not mutate it!
 197  */
 198 size_t opal_btl_usnic_convertor_pack_peek(
 199     const opal_convertor_t *conv,
 200     size_t max_len)
 201 {
 202     int rc;
 203     size_t packable_len, position;
 204     opal_convertor_t temp;
 205 
 206     OBJ_CONSTRUCT(&temp, opal_convertor_t);
 207     position = conv->bConverted + max_len;
 208     rc = opal_convertor_clone_with_position(conv, &temp, 1, &position);
 209     if (OPAL_UNLIKELY(rc < 0)) {
 210         BTL_ERROR(("unexpected convertor error"));
 211         abort(); /* XXX */
 212     }
 213     assert(position >= conv->bConverted);
 214     packable_len = position - conv->bConverted;
 215     OBJ_DESTRUCT(&temp);
 216     return packable_len;
 217 }

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