root/opal/mca/pmix/pmix4x/pmix/src/mca/gds/base/gds_base_fns.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmix_gds_base_get_available_modules
  2. pmix_gds_base_assign_module
  3. pmix_gds_base_setup_fork
  4. pmix_gds_base_store_modex
  5. pmix_gds_base_modex_pack_kval
  6. pmix_gds_base_modex_unpack_kval

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2015-2019 Intel, Inc.  All rights reserved.
   4  * Copyright (c) 2016-2019 Mellanox Technologies, Inc.
   5  *                         All rights reserved.
   6  * Copyright (c) 2018      IBM Corporation.  All rights reserved.
   7  * Copyright (c) 2018-2019 Research Organization for Information Science
   8  *                         and Technology (RIST).  All rights reserved.
   9  *
  10  * $COPYRIGHT$
  11  *
  12  * Additional copyrights may follow
  13  *
  14  * $HEADER$
  15  */
  16 
  17 #include <src/include/pmix_config.h>
  18 
  19 #include <pmix_common.h>
  20 #include "src/include/pmix_globals.h"
  21 
  22 #include "src/class/pmix_list.h"
  23 #include "src/util/argv.h"
  24 #include "src/util/error.h"
  25 
  26 #include "src/mca/gds/base/base.h"
  27 #include "src/server/pmix_server_ops.h"
  28 
  29 
  30 char* pmix_gds_base_get_available_modules(void)
  31 {
  32     if (!pmix_gds_globals.initialized) {
  33         return NULL;
  34     }
  35 
  36     return strdup(pmix_gds_globals.all_mods);
  37 }
  38 
  39 /* Select a gds module per the given directives */
  40 pmix_gds_base_module_t* pmix_gds_base_assign_module(pmix_info_t *info, size_t ninfo)
  41 {
  42     pmix_gds_base_active_module_t *active;
  43     pmix_gds_base_module_t *mod = NULL;
  44     int pri, priority = -1;
  45 
  46     if (!pmix_gds_globals.initialized) {
  47         return NULL;
  48     }
  49 
  50     PMIX_LIST_FOREACH(active, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) {
  51         if (NULL == active->module->assign_module) {
  52             continue;
  53         }
  54         if (PMIX_SUCCESS == active->module->assign_module(info, ninfo, &pri)) {
  55             if (pri < 0) {
  56                 /* use the default priority from the component */
  57                 pri = active->pri;
  58             }
  59             if (priority < pri) {
  60                 mod = active->module;
  61                 priority = pri;
  62             }
  63         }
  64     }
  65 
  66     return mod;
  67 }
  68 
  69 pmix_status_t pmix_gds_base_setup_fork(const pmix_proc_t *proc,
  70                                        char ***env)
  71 {
  72     pmix_gds_base_active_module_t *active;
  73     pmix_status_t rc;
  74 
  75     if (!pmix_gds_globals.initialized) {
  76         return PMIX_ERR_INIT;
  77     }
  78 
  79     PMIX_LIST_FOREACH(active, &pmix_gds_globals.actives, pmix_gds_base_active_module_t) {
  80         if (NULL == active->module->setup_fork) {
  81             continue;
  82         }
  83         if (PMIX_SUCCESS != (rc = active->module->setup_fork(proc, env))) {
  84             return rc;
  85         }
  86     }
  87 
  88     return PMIX_SUCCESS;
  89 }
  90 
  91 pmix_status_t pmix_gds_base_store_modex(struct pmix_namespace_t *nspace,
  92                                         pmix_buffer_t * buff,
  93                                         pmix_gds_base_ctx_t ctx,
  94                                         pmix_gds_base_store_modex_cb_fn_t cb_fn,
  95                                         void *cbdata)
  96 {
  97     pmix_status_t rc = PMIX_SUCCESS;
  98     pmix_buffer_t bkt;
  99     pmix_byte_object_t bo, bo2;
 100     int32_t cnt = 1;
 101     pmix_collect_t ctype;
 102     pmix_server_trkr_t *trk = (pmix_server_trkr_t*)cbdata;
 103     pmix_proc_t proc;
 104     pmix_buffer_t pbkt;
 105     pmix_rank_t rel_rank;
 106     pmix_nspace_caddy_t *nm;
 107     bool found;
 108     char  **kmap = NULL;
 109     uint32_t kmap_size;
 110     pmix_gds_modex_key_fmt_t kmap_type;
 111     pmix_gds_modex_blob_info_t blob_info_byte = 0;
 112 
 113     /* Loop over the enclosed byte object envelopes and
 114      * store them in our GDS module */
 115     cnt = 1;
 116     PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 117             buff, &bo, &cnt, PMIX_BYTE_OBJECT);
 118 
 119     /* If the collect flag is set, we should have some data for unpacking */
 120     if ((PMIX_COLLECT_YES == trk->collect_type) &&
 121             (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc)) {
 122         goto exit;
 123     }
 124 
 125     while (PMIX_SUCCESS == rc) {
 126         PMIX_CONSTRUCT(&bkt, pmix_buffer_t);
 127         PMIX_LOAD_BUFFER(pmix_globals.mypeer, &bkt, bo.bytes, bo.size);
 128         /* unpack the data collection flag */
 129         cnt = 1;
 130         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 131                 &bkt, &blob_info_byte, &cnt, PMIX_BYTE);
 132         if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) {
 133             /* no data was returned, so we are done with this blob */
 134             PMIX_DESTRUCT(&bkt);
 135             break;
 136         }
 137         if (PMIX_SUCCESS != rc) {
 138             /* we have an error */
 139             PMIX_ERROR_LOG(rc);
 140             PMIX_DESTRUCT(&bkt);
 141             goto exit;
 142         }
 143         /* Check that this blob was accumulated with the same data collection
 144          * setting */
 145         ctype = PMIX_GDS_COLLECT_IS_SET(blob_info_byte) ?
 146                     PMIX_COLLECT_YES : PMIX_COLLECT_NO;
 147         if (trk->collect_type != ctype) {
 148             rc = PMIX_ERR_INVALID_ARG;
 149             PMIX_ERROR_LOG(rc);
 150             goto exit;
 151         }
 152 
 153         /* determine the key-map existing flag */
 154         kmap_type = PMIX_GDS_KEYMAP_IS_SET(blob_info_byte) ?
 155                     PMIX_MODEX_KEY_KEYMAP_FMT : PMIX_MODEX_KEY_NATIVE_FMT;
 156         if (PMIX_MODEX_KEY_KEYMAP_FMT == kmap_type) {
 157             /* unpack the size of uniq keys names in the map */
 158             cnt = 1;
 159             PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 160                                &bkt, &kmap_size, &cnt, PMIX_UINT32);
 161             if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) {
 162                 rc = PMIX_SUCCESS;
 163                 PMIX_DESTRUCT(&bkt);
 164                 break;
 165             } else if (PMIX_SUCCESS != rc) {
 166                 PMIX_ERROR_LOG(rc);
 167                 PMIX_DESTRUCT(&bkt);
 168                 break;
 169             }
 170 
 171             /* init and unpack key names map, the position of the key name
 172              * in the array determines the unique key index */
 173             kmap = (char**)(calloc(kmap_size + 1, sizeof(char*)));
 174             if (NULL == kmap) {
 175                 rc = PMIX_ERR_OUT_OF_RESOURCE;
 176                 PMIX_ERROR_LOG(rc);
 177                 goto exit;
 178             }
 179             cnt = kmap_size;
 180             PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &bkt,
 181                                kmap, &cnt, PMIX_STRING);
 182             if (PMIX_SUCCESS != rc) {
 183                 PMIX_ERROR_LOG(rc);
 184                 PMIX_DESTRUCT(&bkt);
 185                 goto exit;
 186             }
 187             if (pmix_argv_count(kmap) != (int)kmap_size) {
 188                 rc = PMIX_ERR_UNPACK_FAILURE;
 189                 PMIX_ERROR_LOG(rc);
 190                 PMIX_DESTRUCT(&bkt);
 191                 goto exit;
 192             }
 193         }
 194         /* unpack the enclosed blobs from the various peers */
 195         cnt = 1;
 196         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 197                 &bkt, &bo2, &cnt, PMIX_BYTE_OBJECT);
 198         while (PMIX_SUCCESS == rc) {
 199             /* unpack all the kval's from this peer and store them in
 200              * our GDS. Note that PMIx by design holds all data at
 201              * the server level until requested. If our GDS is a
 202              * shared memory region, then the data may be available
 203              * right away - but the client still has to be notified
 204              * of its presence. */
 205 
 206             /* setup the byte object for unpacking */
 207             PMIX_CONSTRUCT(&pbkt, pmix_buffer_t);
 208             PMIX_LOAD_BUFFER(pmix_globals.mypeer, &pbkt, bo2.bytes, bo2.size);
 209             /* unload the proc that provided this data */
 210             cnt = 1;
 211             PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, &pbkt, &rel_rank, &cnt,
 212                                PMIX_PROC_RANK);
 213             if (PMIX_SUCCESS != rc) {
 214                 PMIX_ERROR_LOG(rc);
 215                 pbkt.base_ptr = NULL;
 216                 PMIX_DESTRUCT(&pbkt);
 217                 break;
 218             }
 219             found = false;
 220             /* calculate proc form the relative rank */
 221             if (pmix_list_get_size(&trk->nslist) == 1) {
 222                 found = true;
 223                 nm = (pmix_nspace_caddy_t*)pmix_list_get_first(&trk->nslist);
 224             } else {
 225                 PMIX_LIST_FOREACH(nm, &trk->nslist, pmix_nspace_caddy_t) {
 226                     if (rel_rank < nm->ns->nprocs) {
 227                         found = true;
 228                         break;
 229                     }
 230                     rel_rank -= nm->ns->nprocs;
 231                 }
 232             }
 233             if (false == found) {
 234                 rc = PMIX_ERR_NOT_FOUND;
 235                 PMIX_ERROR_LOG(rc);
 236                 pbkt.base_ptr = NULL;
 237                 PMIX_DESTRUCT(&pbkt);
 238                 break;
 239             }
 240             PMIX_PROC_LOAD(&proc, nm->ns->nspace, rel_rank);
 241 
 242             /* call a specific GDS function to storing
 243              * part of the process data */
 244             rc = cb_fn(ctx, &proc, kmap_type, kmap, &pbkt);
 245             if (PMIX_SUCCESS != rc) {
 246                 PMIX_ERROR_LOG(rc);
 247                 pbkt.base_ptr = NULL;
 248                 PMIX_DESTRUCT(&pbkt);
 249                 break;
 250             }
 251             pbkt.base_ptr = NULL;
 252             PMIX_DESTRUCT(&pbkt);
 253             PMIX_BYTE_OBJECT_DESTRUCT(&bo2);
 254             /* get the next blob */
 255             cnt = 1;
 256             PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 257                     &bkt, &bo2, &cnt, PMIX_BYTE_OBJECT);
 258         }
 259         PMIX_DESTRUCT(&bkt);
 260 
 261         if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) {
 262             rc = PMIX_SUCCESS;
 263         } else if (PMIX_SUCCESS != rc) {
 264             PMIX_ERROR_LOG(rc);
 265             goto exit;
 266         }
 267         /* unpack and process the next blob */
 268         cnt = 1;
 269         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer,
 270                 buff, &bo, &cnt, PMIX_BYTE_OBJECT);
 271     }
 272 
 273     if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER == rc) {
 274         rc = PMIX_SUCCESS;
 275     } else if (PMIX_SUCCESS != rc) {
 276         PMIX_ERROR_LOG(rc);
 277     }
 278 exit:
 279     pmix_argv_free(kmap);
 280     return rc;
 281 }
 282 
 283 /*
 284  * Pack the key-value as a tuple of key-name index and key-value.
 285  * The key-name to store replaced by unique key-index that stored
 286  * to the key-map. So the remote server can determine the key-name
 287  * by the index from map that packed in modex as well.
 288  *
 289  * kmap - key values array by (char*), uses to store unique key
 290  *        names string and determine their indexes
 291  *
 292  * buf - output buffer to pack key-values
 293  *
 294  * kv - pmix key-value pair
 295  */
 296 pmix_status_t pmix_gds_base_modex_pack_kval(pmix_gds_modex_key_fmt_t key_fmt,
 297                                             pmix_buffer_t *buf, char ***kmap,
 298                                             pmix_kval_t *kv)
 299 {
 300     uint32_t key_idx;
 301     pmix_status_t rc = PMIX_SUCCESS;
 302 
 303     if (PMIX_MODEX_KEY_KEYMAP_FMT == key_fmt) {
 304         rc = pmix_argv_append_unique_idx((int*)&key_idx, kmap, kv->key);
 305         if (PMIX_SUCCESS != rc) {
 306             PMIX_ERROR_LOG(rc);
 307             return rc;
 308         }
 309         /* pack key-index */
 310         PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, buf, &key_idx, 1, PMIX_UINT32);
 311         if (PMIX_SUCCESS != rc) {
 312             PMIX_ERROR_LOG(rc);
 313             return rc;
 314         }
 315         /* pack key-value */
 316         PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, buf, kv->value, 1, PMIX_VALUE);
 317         if (PMIX_SUCCESS != rc) {
 318             PMIX_ERROR_LOG(rc);
 319             return rc;
 320         }
 321     } else if (PMIX_MODEX_KEY_NATIVE_FMT == key_fmt) {
 322         PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, buf, kv, 1, PMIX_KVAL);
 323         if (PMIX_SUCCESS != rc) {
 324             PMIX_ERROR_LOG(rc);
 325             return rc;
 326         }
 327     } else {
 328         rc = PMIX_ERR_BAD_PARAM;
 329         PMIX_ERROR_LOG(rc);
 330         return rc;
 331     }
 332 
 333     return PMIX_SUCCESS;
 334 }
 335 
 336 /*
 337  * Unpack the key-value as a tuple of key-name index and key-value.
 338  *
 339  * kmap - key values array by (char*), uses to store unique key
 340  *        names string and determine their indexes
 341  *
 342  * buf - input buffer to unpack key-values
 343  *
 344  * kv - unpacked pmix key-value pair
 345  */
 346 pmix_status_t pmix_gds_base_modex_unpack_kval(pmix_gds_modex_key_fmt_t key_fmt,
 347                                               pmix_buffer_t *buf, char **kmap,
 348                                               pmix_kval_t *kv)
 349 {
 350     int32_t cnt;
 351     uint32_t key_idx;
 352     pmix_status_t rc = PMIX_SUCCESS;
 353 
 354     if (PMIX_MODEX_KEY_KEYMAP_FMT == key_fmt) {
 355         cnt = 1;
 356         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, buf, &key_idx, &cnt, PMIX_UINT32);
 357         if (PMIX_SUCCESS != rc) {
 358             return rc;
 359         }
 360         // sanity check
 361         if (NULL == kmap[key_idx]) {
 362             rc = PMIX_ERR_BAD_PARAM;
 363             PMIX_ERROR_LOG(rc);
 364             return rc;
 365         }
 366         kv->key = strdup(kmap[key_idx]);
 367         cnt = 1;
 368         PMIX_VALUE_CREATE(kv->value, 1);
 369         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, buf, kv->value, &cnt, PMIX_VALUE);
 370         if (PMIX_SUCCESS != rc) {
 371             free(kv->key);
 372             PMIX_VALUE_RELEASE(kv->value);
 373             PMIX_ERROR_LOG(rc);
 374             return rc;
 375         }
 376     } else if (PMIX_MODEX_KEY_NATIVE_FMT == key_fmt) {
 377         cnt = 1;
 378         PMIX_BFROPS_UNPACK(rc, pmix_globals.mypeer, buf, kv, &cnt, PMIX_KVAL);
 379         if (PMIX_SUCCESS != rc) {
 380             return rc;
 381         }
 382     } else {
 383         rc = PMIX_ERR_BAD_PARAM;
 384         PMIX_ERROR_LOG(rc);
 385         return rc;
 386     }
 387 
 388     return PMIX_SUCCESS;
 389 }

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