root/opal/mca/pmix/pmix4x/pmix/src/client/pmi2.c

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

DEFINITIONS

This source file includes following definitions.
  1. PMI2_Init
  2. PMI2_Initialized
  3. PMI2_Finalize
  4. PMI2_Abort
  5. PMI2_Job_Spawn
  6. PMI2_Job_GetId
  7. PMI2_Job_GetRank
  8. PMI2_Info_GetSize
  9. PMI2_Job_Connect
  10. PMI2_Job_Disconnect
  11. PMI2_KVS_Put
  12. PMI2_KVS_Fence
  13. PMI2_KVS_Get
  14. PMI2_Info_GetNodeAttr
  15. PMI2_Info_GetNodeAttrIntArray
  16. PMI2_Info_PutNodeAttr
  17. PMI2_Info_GetJobAttr
  18. PMI2_Info_GetJobAttrIntArray
  19. PMI2_Nameserv_publish
  20. PMI2_Nameserv_lookup
  21. PMI2_Nameserv_unpublish
  22. convert_int
  23. convert_err

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014-2018 Intel, Inc. All rights reserved.
   4  * Copyright (c) 2015-2019 Research Organization for Information Science
   5  *                         and Technology (RIST).  All rights reserved.
   6  * Copyright (c) 2016      Mellanox Technologies, Inc.
   7  *                         All rights reserved.
   8  * $COPYRIGHT$
   9  *
  10  * Additional copyrights may follow
  11  *
  12  * $HEADER$
  13  */
  14 
  15 #include <src/include/pmix_config.h>
  16 
  17 #ifdef HAVE_STRING_H
  18 #include <string.h>
  19 #endif
  20 #ifdef HAVE_UNISTD_H
  21 #include <unistd.h>
  22 #endif
  23 #ifdef HAVE_STDLIB_H
  24 #include <stdlib.h>
  25 #endif
  26 #include PMIX_EVENT_HEADER
  27 
  28 #include <pmi2.h>
  29 #include <pmix.h>
  30 
  31 #include "src/mca/bfrops/bfrops.h"
  32 #include "src/util/argv.h"
  33 #include "src/util/error.h"
  34 #include "src/util/output.h"
  35 #include "src/include/pmix_globals.h"
  36 
  37 #define ANL_MAPPING "PMI_process_mapping"
  38 
  39 #define PMI2_CHECK()                \
  40     do {                            \
  41         if (!pmi2_init) {           \
  42             return PMI2_FAIL;       \
  43         }                           \
  44     } while (0)
  45 
  46 /* local functions */
  47 static pmix_status_t convert_int(int *value, pmix_value_t *kv);
  48 static int convert_err(pmix_status_t rc);
  49 static pmix_proc_t myproc;
  50 static int pmi2_init = 0;
  51 static bool commit_reqd = false;
  52 static bool pmi2_singleton = false;
  53 
  54 PMIX_EXPORT int PMI2_Init(int *spawned, int *size, int *rank, int *appnum)
  55 {
  56     pmix_status_t rc = PMIX_SUCCESS;
  57     pmix_value_t *val;
  58     pmix_info_t info[1];
  59     bool  val_optinal = 1;
  60     pmix_proc_t proc = myproc;
  61     proc.rank = PMIX_RANK_WILDCARD;
  62 
  63     if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) {
  64         /* if we didn't see a PMIx server (e.g., missing envar),
  65          * then allow us to run as a singleton */
  66         if (PMIX_ERR_INVALID_NAMESPACE == rc) {
  67             if (NULL != spawned) {
  68                 *spawned = 0;
  69             }
  70             if (NULL != size) {
  71                 *size = 1;
  72             }
  73             if (NULL != rank) {
  74                 *rank = 0;
  75             }
  76             if (NULL != appnum) {
  77                 *appnum = 0;
  78             }
  79             pmi2_singleton = true;
  80             pmix_strncpy(myproc.nspace, "1234", PMIX_MAX_NSLEN);
  81             myproc.rank = 0;
  82             pmi2_init = 1;
  83             return PMI2_SUCCESS;
  84         }
  85         return PMI2_ERR_INIT;
  86     }
  87 
  88     /* get the rank */
  89     *rank = myproc.rank;
  90 
  91     /* set controlling parameters
  92      * PMIX_OPTIONAL - expect that these keys should be available on startup
  93      */
  94     PMIX_INFO_CONSTRUCT(&info[0]);
  95     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
  96 
  97     if (NULL != size) {
  98         /* get the universe size - this will likely pull
  99          * down all attributes assigned to the job, thus
 100          * making all subsequent "get" operations purely
 101          * local */
 102         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_UNIV_SIZE, info, 1, &val)) {
 103             rc = convert_int(size, val);
 104             PMIX_VALUE_RELEASE(val);
 105             if (PMIX_SUCCESS != rc) {
 106                 goto error;
 107             }
 108         } else {
 109             /* cannot continue without this info */
 110             rc = PMIX_ERR_INIT;
 111             goto error;
 112         }
 113     }
 114 
 115     if (NULL != spawned) {
 116         /* get the spawned flag */
 117         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_SPAWNED, info, 1, &val)) {
 118             rc = convert_int(spawned, val);
 119             PMIX_VALUE_RELEASE(val);
 120             if (PMIX_SUCCESS != rc) {
 121                 goto error;
 122             }
 123         } else {
 124             /* if not found, default to not spawned */
 125             *spawned = 0;
 126         }
 127     }
 128 
 129     if (NULL != appnum) {
 130         /* get our appnum */
 131         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_APPNUM, info, 1, &val)) {
 132             rc = convert_int(appnum, val);
 133             PMIX_VALUE_RELEASE(val);
 134             if (PMIX_SUCCESS != rc) {
 135                 goto error;
 136             }
 137         } else {
 138             /* if not found, default to 0 */
 139             *appnum = 0;
 140         }
 141     }
 142     pmi2_init = 1;
 143 
 144     rc = PMIX_SUCCESS;
 145 
 146 error:
 147     PMIX_INFO_DESTRUCT(&info[0]);
 148 
 149     return convert_err(rc);
 150 }
 151 
 152 PMIX_EXPORT int PMI2_Initialized(void)
 153 {
 154     int initialized;
 155     if (pmi2_singleton) {
 156         return 1;
 157     }
 158 
 159     initialized = (int)PMIx_Initialized();
 160     return initialized;
 161 }
 162 
 163 PMIX_EXPORT int PMI2_Finalize(void)
 164 {
 165     pmix_status_t rc = PMIX_SUCCESS;
 166 
 167     PMI2_CHECK();
 168 
 169     pmi2_init = 0;
 170     if (pmi2_singleton) {
 171         return PMI2_SUCCESS;
 172     }
 173 
 174     rc = PMIx_Finalize(NULL, 0);
 175     return convert_err(rc);
 176 }
 177 
 178 PMIX_EXPORT int PMI2_Abort(int flag, const char msg[])
 179 {
 180     pmix_status_t rc = PMIX_SUCCESS;
 181 
 182     PMI2_CHECK();
 183 
 184     if (pmi2_singleton) {
 185         return PMI2_SUCCESS;
 186     }
 187 
 188     rc = PMIx_Abort(flag, msg, NULL, 0);
 189     return convert_err(rc);
 190 }
 191 
 192 PMIX_EXPORT int PMI2_Job_Spawn(int count, const char * cmds[],
 193                    int argcs[], const char ** argvs[],
 194                    const int maxprocs[],
 195                    const int info_keyval_sizes[],
 196                    const PMI_keyval_t *info_keyval_vectors[],
 197                    int preput_keyval_size,
 198                    const PMI_keyval_t *preput_keyval_vector[],
 199                    char jobId[], int jobIdSize,
 200                    int errors[])
 201 {
 202     pmix_status_t rc = PMIX_SUCCESS;
 203     pmix_app_t *apps;
 204     int i, k;
 205     size_t j;
 206     char *evar;
 207 
 208     PMI2_CHECK();
 209 
 210     if (NULL == cmds) {
 211         return PMI2_ERR_INVALID_ARGS;
 212     }
 213 
 214     if (pmi2_singleton) {
 215         return PMI2_FAIL;
 216     }
 217 
 218     /* setup the apps */
 219     PMIX_APP_CREATE(apps, count);
 220     for (i=0; i < count; i++) {
 221         apps[i].cmd = strdup(cmds[i]);
 222         apps[i].maxprocs = maxprocs[i];
 223         apps[i].argv = pmix_argv_copy((char**)argvs[i]);
 224         apps[i].ninfo = info_keyval_sizes[i];
 225         apps[i].info = (pmix_info_t*)malloc(apps[i].ninfo * sizeof(pmix_info_t));
 226         /* copy the info objects */
 227         for (j=0; j < apps[i].ninfo; j++) {
 228             pmix_strncpy(apps[i].info[j].key, info_keyval_vectors[i][j].key, PMIX_MAX_KEYLEN);
 229             apps[i].info[j].value.type = PMIX_STRING;
 230             apps[i].info[j].value.data.string = strdup(info_keyval_vectors[i][j].val);
 231         }
 232         /* push the preput values into the apps environ */
 233         for (k=0; k < preput_keyval_size; k++) {
 234             if (0 > asprintf(&evar, "%s=%s", preput_keyval_vector[j]->key, preput_keyval_vector[j]->val)) {
 235                 for (i = 0; i < count; i++) {
 236                     PMIX_APP_DESTRUCT(&apps[i]);
 237                 }
 238                 free(apps);
 239                 return PMIX_ERR_NOMEM;
 240             }
 241             pmix_argv_append_nosize(&apps[i].env, evar);
 242             free(evar);
 243         }
 244     }
 245 
 246     rc = PMIx_Spawn(NULL, 0, apps, count, NULL);
 247     /* tear down the apps array */
 248     for (i=0; i < count; i++) {
 249         PMIX_APP_DESTRUCT(&apps[i]);
 250     }
 251     free(apps);
 252     if (NULL != errors) {
 253         for (i=0; i < count; i++) {
 254             errors[i] = convert_err(rc);
 255         }
 256     }
 257 
 258     return convert_err(rc);
 259 }
 260 
 261 PMIX_EXPORT int PMI2_Job_GetId(char jobid[], int jobid_size)
 262 {
 263     /* we already obtained our nspace during pmi2_init,
 264      * so all we have to do here is return it */
 265 
 266     PMI2_CHECK();
 267 
 268     /* bozo check */
 269     if (NULL == jobid) {
 270         return PMI2_ERR_INVALID_ARGS;
 271     }
 272     pmix_strncpy(jobid, myproc.nspace, jobid_size-1);
 273     return PMI2_SUCCESS;
 274 }
 275 
 276 PMIX_EXPORT int PMI2_Job_GetRank(int *rank)
 277 {
 278     PMI2_CHECK();
 279 
 280     if (NULL == rank) {
 281         return PMI2_ERR_INVALID_ARGS;
 282     }
 283     *rank = myproc.rank;
 284     return PMI2_SUCCESS;
 285 }
 286 
 287 PMIX_EXPORT int PMI2_Info_GetSize(int *size)
 288 {
 289     pmix_status_t rc = PMIX_ERROR;
 290     pmix_value_t *val;
 291     pmix_info_t info[1];
 292     bool  val_optinal = 1;
 293     pmix_proc_t proc = myproc;
 294     proc.rank = PMIX_RANK_WILDCARD;
 295 
 296 
 297     PMI2_CHECK();
 298 
 299     if (NULL == size) {
 300         return PMI2_ERR_INVALID_ARGS;
 301     }
 302 
 303     if (pmi2_singleton) {
 304         *size = 1;
 305         return PMI2_SUCCESS;
 306     }
 307 
 308     /* set controlling parameters
 309      * PMIX_OPTIONAL - expect that these keys should be available on startup
 310      */
 311     PMIX_INFO_CONSTRUCT(&info[0]);
 312     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 313 
 314     if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_LOCAL_SIZE, info, 1, &val)) {
 315         rc = convert_int(size, val);
 316         PMIX_VALUE_RELEASE(val);
 317     }
 318 
 319     PMIX_INFO_DESTRUCT(&info[0]);
 320 
 321     return convert_err(rc);
 322 }
 323 
 324 PMIX_EXPORT int PMI2_Job_Connect(const char jobid[], PMI2_Connect_comm_t *conn)
 325 {
 326     pmix_status_t rc = PMIX_SUCCESS;
 327     pmix_proc_t proc;
 328 
 329     PMI2_CHECK();
 330 
 331     if (NULL == conn) {
 332         return PMI2_ERR_INVALID_ARGS;
 333     }
 334 
 335     if (pmi2_singleton) {
 336         return PMI2_FAIL;
 337     }
 338 
 339     memset(proc.nspace, 0, sizeof(proc.nspace));
 340     pmix_strncpy(proc.nspace, (jobid ? jobid : proc.nspace), PMIX_MAX_NSLEN);
 341     proc.rank = PMIX_RANK_WILDCARD;
 342     rc = PMIx_Connect(&proc, 1, NULL, 0);
 343     return convert_err(rc);
 344 }
 345 
 346 PMIX_EXPORT int PMI2_Job_Disconnect(const char jobid[])
 347 {
 348     pmix_status_t rc = PMIX_SUCCESS;
 349     pmix_proc_t proc;
 350 
 351     PMI2_CHECK();
 352 
 353     if (pmi2_singleton) {
 354         return PMI2_SUCCESS;
 355     }
 356 
 357     memset(proc.nspace, 0, sizeof(proc.nspace));
 358     pmix_strncpy(proc.nspace, (jobid ? jobid : proc.nspace), PMIX_MAX_NSLEN);
 359     proc.rank = PMIX_RANK_WILDCARD;
 360     rc = PMIx_Disconnect(&proc, 1, NULL, 0);
 361     return convert_err(rc);
 362 }
 363 
 364 /* KVS_Put - we default to PMIX_GLOBAL scope */
 365 PMIX_EXPORT int PMI2_KVS_Put(const char key[], const char value[])
 366 {
 367     pmix_status_t rc = PMIX_SUCCESS;
 368     pmix_value_t val;
 369 
 370     PMI2_CHECK();
 371 
 372     if ((NULL == key) || (NULL == value)) {
 373         return PMI2_ERR_INVALID_ARG;
 374     }
 375 
 376     if (pmi2_singleton) {
 377         return PMI2_SUCCESS;
 378     }
 379 
 380     pmix_output_verbose(3, pmix_globals.debug_output,
 381             "PMI2_KVS_Put: key=%s value=%s", key, value);
 382 
 383     val.type = PMIX_STRING;
 384     val.data.string = (char*)value;
 385     if (PMIX_SUCCESS == (rc = PMIx_Put(PMIX_GLOBAL, key, &val))) {
 386         commit_reqd = true;
 387     }
 388     return convert_err(rc);
 389 }
 390 
 391 /* KVS_Fence */
 392 PMIX_EXPORT int PMI2_KVS_Fence(void)
 393 {
 394     pmix_status_t rc = PMIX_SUCCESS;
 395 
 396     PMI2_CHECK();
 397 
 398     pmix_output_verbose(3, pmix_globals.debug_output, "PMI2_KVS_Fence");
 399 
 400     if (pmi2_singleton) {
 401         return PMI2_SUCCESS;
 402     }
 403 
 404     if (PMIX_SUCCESS != (rc = PMIx_Commit())) {
 405         return convert_err(rc);
 406     }
 407     commit_reqd = false;
 408 
 409     /* we want all data to be collected upon completion */
 410     {
 411         pmix_info_t info[1];
 412         bool  val_data = 1;
 413 
 414         /* set controlling parameters
 415          * PMIX_COLLECT_DATA - meet legacy PMI2 requirement
 416          */
 417         PMIX_INFO_CONSTRUCT(&info[0]);
 418         PMIX_INFO_LOAD(&info[0], PMIX_COLLECT_DATA, &val_data, PMIX_BOOL);
 419 
 420         rc = PMIx_Fence(NULL, 0, &info[0], 1);
 421         PMIX_INFO_DESTRUCT(&info[0]);
 422     }
 423 
 424     return convert_err(rc);
 425 }
 426 
 427 /* the jobid is equated to the nspace in PMIx, and the
 428  * src_pmi_id equates to the rank. If jobid=NULL, then PMIx
 429  * will use the local nspace, which matches the PMI2 spec.
 430  * The only type of value supported by PMI2 is a string, so
 431  * the return of anything else is an error */
 432 PMIX_EXPORT int PMI2_KVS_Get(const char *jobid, int src_pmi_id,
 433                              const char key[], char value [],
 434                              int maxvalue, int *vallen)
 435 {
 436     pmix_status_t rc = PMIX_SUCCESS;
 437     pmix_value_t *val;
 438     pmix_proc_t proc;
 439 
 440     PMI2_CHECK();
 441 
 442     if (commit_reqd) {
 443         /* they didn't commit after a put */
 444         return PMI2_FAIL;
 445     }
 446     /* set default */
 447     *vallen = 0;
 448 
 449     if ((NULL == key) || (NULL == value)) {
 450         return PMI2_ERR_INVALID_ARG;
 451     }
 452 
 453     pmix_output_verbose(3, pmix_globals.debug_output,
 454             "PMI2_KVS_Get: key=%s jobid=%s src_pmi_id=%d", key, (jobid ? jobid : "null"), src_pmi_id);
 455 
 456     pmix_strncpy(proc.nspace, (jobid ? jobid : myproc.nspace), PMIX_MAX_NSLEN);
 457     if (src_pmi_id == PMI2_ID_NULL) {
 458         /* the rank is UNDEF */
 459         proc.rank = PMIX_RANK_UNDEF;
 460     } else {
 461         proc.rank = src_pmi_id;
 462     }
 463 
 464     rc = PMIx_Get(&proc, key, NULL, 0, &val);
 465     if (PMIX_SUCCESS == rc && NULL != val) {
 466         if (PMIX_STRING != val->type) {
 467             rc = PMIX_ERROR;
 468         } else if (NULL != val->data.string) {
 469             pmix_strncpy(value, val->data.string, maxvalue-1);
 470             *vallen = strlen(val->data.string);
 471         }
 472         PMIX_VALUE_RELEASE(val);
 473     }
 474 
 475     return convert_err(rc);
 476 }
 477 
 478 PMIX_EXPORT int PMI2_Info_GetNodeAttr(const char name[],
 479                                       char value[], int valuelen,
 480                                       int *found, int waitfor)
 481 {
 482     pmix_status_t rc = PMIX_SUCCESS;
 483     pmix_value_t *val;
 484     pmix_info_t info[1];
 485     bool  val_optinal = 1;
 486     pmix_proc_t proc = myproc;
 487     proc.rank = PMIX_RANK_UNDEF;
 488 
 489     PMI2_CHECK();
 490 
 491     if ((NULL == name) || (NULL == value) || (NULL == found)) {
 492         return PMI2_ERR_INVALID_ARG;
 493     }
 494 
 495     if (pmi2_singleton) {
 496         return PMI2_FAIL;
 497     }
 498 
 499     /* set controlling parameters
 500      * PMIX_OPTIONAL - expect that these keys should be available on startup
 501      */
 502     PMIX_INFO_CONSTRUCT(&info[0]);
 503     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 504 
 505     *found = 0;
 506     /* TODO: does PMI2's "name" makes sense to PMIx? */
 507     rc = PMIx_Get(&proc, name, info, 1, &val);
 508     if (PMIX_SUCCESS == rc && NULL != val) {
 509         if (PMIX_STRING != val->type) {
 510             rc = PMIX_ERROR;
 511         } else if (NULL != val->data.string) {
 512             pmix_strncpy(value, val->data.string, valuelen-1);
 513             *found = 1;
 514         }
 515         PMIX_VALUE_RELEASE(val);
 516     } else if (PMIX_ERR_NOT_FOUND == rc) {
 517         rc = PMIX_SUCCESS;
 518     }
 519 
 520     PMIX_INFO_DESTRUCT(&info[0]);
 521 
 522     return convert_err(rc);
 523 }
 524 
 525 PMIX_EXPORT int PMI2_Info_GetNodeAttrIntArray(const char name[], int array[],
 526                                   int arraylen, int *outlen, int *found)
 527 {
 528     return PMI2_FAIL;
 529 }
 530 
 531 /* push info at the PMIX_LOCAL scope */
 532 PMIX_EXPORT int PMI2_Info_PutNodeAttr(const char name[], const char value[])
 533 {
 534     pmix_status_t rc = PMIX_SUCCESS;
 535     pmix_value_t val;
 536 
 537     PMI2_CHECK();
 538 
 539     if ((NULL == name) || (NULL == value)) {
 540         return PMI2_ERR_INVALID_ARG;
 541     }
 542 
 543     if (pmi2_singleton) {
 544         return PMI2_SUCCESS;
 545     }
 546 
 547     val.type = PMIX_STRING;
 548     val.data.string = (char*)value;
 549     rc = PMIx_Put(PMIX_LOCAL, name, &val);
 550     return convert_err(rc);
 551 }
 552 
 553 PMIX_EXPORT int PMI2_Info_GetJobAttr(const char name[], char value[], int valuelen, int *found)
 554 {
 555     pmix_status_t rc = PMIX_SUCCESS;
 556     pmix_value_t *val;
 557     pmix_info_t info[1];
 558     bool  val_optinal = 1;
 559     pmix_proc_t proc = myproc;
 560     proc.rank = PMIX_RANK_UNDEF;
 561 
 562     PMI2_CHECK();
 563 
 564     if ((NULL == name) || (NULL == value) || (NULL == found)) {
 565         return PMI2_ERR_INVALID_ARG;
 566     }
 567 
 568     if (pmi2_singleton) {
 569         return PMI2_FAIL;
 570     }
 571 
 572     /* set controlling parameters
 573      * PMIX_OPTIONAL - expect that these keys should be available on startup
 574      */
 575     PMIX_INFO_CONSTRUCT(&info[0]);
 576     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 577 
 578     /* PMI-2 expects resource manager to set
 579      * process mapping in ANL notation. */
 580     if (!strcmp(name, ANL_MAPPING)) {
 581         /* we are looking in the job-data. If there is nothing there
 582          * we don't want to look in rank's data, thus set rank to widcard */
 583         proc = myproc;
 584         proc.rank = PMIX_RANK_WILDCARD;
 585         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_ANL_MAP, NULL, 0, &val) &&
 586                (NULL != val) && (PMIX_STRING == val->type)) {
 587             pmix_strncpy(value, val->data.string, valuelen);
 588             PMIX_VALUE_FREE(val, 1);
 589             *found = 1;
 590             return PMI2_SUCCESS;
 591         } else {
 592             /* artpol:
 593              * Some RM's (i.e. SLURM) already have ANL precomputed. The export it
 594              * through PMIX_ANL_MAP variable.
 595              * If we haven't found it we want to have our own packing functionality
 596              * since it's common.
 597              * Somebody else has to write it since I've already done that for
 598              * GPL'ed SLURM :) */
 599             *found = 1;
 600             return PMI2_FAIL;
 601         }
 602     }
 603 
 604 
 605     *found = 0;
 606     rc = PMIx_Get(&proc, name, info, 1, &val);
 607     if (PMIX_SUCCESS == rc && NULL != val) {
 608         if (PMIX_STRING != val->type) {
 609             rc = PMIX_ERROR;
 610         } else if (NULL != val->data.string) {
 611             pmix_strncpy(value, val->data.string, valuelen-1);
 612             *found = 1;
 613         }
 614         PMIX_VALUE_RELEASE(val);
 615     } else if (PMIX_ERR_NOT_FOUND == rc) {
 616         rc = PMIX_SUCCESS;
 617     }
 618 
 619     PMIX_INFO_DESTRUCT(&info[0]);
 620 
 621     return convert_err(rc);
 622 }
 623 
 624 PMIX_EXPORT int PMI2_Info_GetJobAttrIntArray(const char name[],
 625                                              int array[], int arraylen,
 626                                              int *outlen, int *found)
 627 {
 628     return PMI2_FAIL;
 629 }
 630 
 631 PMIX_EXPORT int PMI2_Nameserv_publish(const char service_name[],
 632                                       const PMI_keyval_t *info_ptr, const char port[])
 633 {
 634     pmix_status_t rc = PMIX_SUCCESS;
 635     int nvals;
 636     pmix_info_t info[2];
 637 
 638     PMI2_CHECK();
 639 
 640     if (NULL == service_name || NULL == port) {
 641         return PMI2_ERR_INVALID_ARG;
 642     }
 643 
 644     if (pmi2_singleton) {
 645         return PMI2_FAIL;
 646     }
 647 
 648     /* pass the service/port */
 649     pmix_strncpy(info[0].key, service_name, PMIX_MAX_KEYLEN);
 650     info[0].value.type = PMIX_STRING;
 651     info[0].value.data.string = (char*)port;
 652     nvals = 1;
 653 
 654     /* if provided, add any other value */
 655     if (NULL != info_ptr) {
 656         pmix_strncpy(info[1].key, info_ptr->key, PMIX_MAX_KEYLEN);
 657         info[1].value.type = PMIX_STRING;
 658         info[1].value.data.string = (char*)info_ptr->val;
 659         nvals = 2;
 660     }
 661     /* publish the info - PMI-2 doesn't support
 662      * any scope other than inside our own nspace */
 663     rc = PMIx_Publish(info, nvals);
 664 
 665     return convert_err(rc);
 666 }
 667 
 668 PMIX_EXPORT int PMI2_Nameserv_lookup(const char service_name[],
 669                                      const PMI_keyval_t *info_ptr,
 670                                      char port[], int portLen)
 671 {
 672     pmix_status_t rc = PMIX_SUCCESS;
 673     int nvals;
 674     pmix_pdata_t pdata[2];
 675 
 676     PMI2_CHECK();
 677 
 678     if (NULL == service_name || NULL == info_ptr || NULL == port) {
 679         return PMI2_ERR_INVALID_ARG;
 680     }
 681 
 682     if (pmi2_singleton) {
 683         return PMI2_FAIL;
 684     }
 685 
 686     PMIX_PDATA_CONSTRUCT(&pdata[0]);
 687     PMIX_PDATA_CONSTRUCT(&pdata[1]);
 688 
 689     /* pass the service */
 690     pmix_strncpy(pdata[0].key, service_name, PMIX_MAX_KEYLEN);
 691     nvals = 1;
 692 
 693     /* if provided, add any other value */
 694     if (NULL != info_ptr) {
 695         pmix_strncpy(pdata[1].key, info_ptr->key, PMIX_MAX_KEYLEN);
 696         pdata[1].value.type = PMIX_STRING;
 697         pdata[1].value.data.string = info_ptr->val;
 698         nvals = 2;
 699     }
 700 
 701     /* lookup the info */
 702     if (PMIX_SUCCESS != (rc = PMIx_Lookup(pdata, nvals, NULL, 0))) {
 703         PMIX_PDATA_DESTRUCT(&pdata[0]);
 704         PMIX_PDATA_DESTRUCT(&pdata[1]);
 705         return convert_err(rc);
 706     }
 707 
 708     /* should have received a string back */
 709     if (PMIX_STRING != pdata[0].value.type ||
 710         NULL == pdata[0].value.data.string) {
 711         PMIX_PDATA_DESTRUCT(&pdata[0]);
 712         PMIX_PDATA_DESTRUCT(&pdata[1]);
 713         return PMI2_FAIL;
 714     }
 715 
 716     /* return the port */
 717     pmix_strncpy(port, pdata[0].value.data.string, portLen-1);
 718     PMIX_PDATA_DESTRUCT(&pdata[0]);
 719 
 720     if (NULL != info_ptr) {
 721     }
 722     PMIX_PDATA_DESTRUCT(&pdata[1]);
 723 
 724     return PMI2_SUCCESS;
 725 }
 726 
 727 PMIX_EXPORT int PMI2_Nameserv_unpublish(const char service_name[],
 728                            const PMI_keyval_t *info_ptr)
 729 {
 730     pmix_status_t rc = PMIX_SUCCESS;
 731     char *keys[3];
 732 
 733     PMI2_CHECK();
 734 
 735     if (NULL == service_name || NULL == info_ptr) {
 736         return PMI2_ERR_INVALID_ARG;
 737     }
 738 
 739     if (pmi2_singleton) {
 740         return PMI2_FAIL;
 741     }
 742 
 743     /* pass the service */
 744     keys[0] = (char*)service_name;
 745     keys[1] = NULL;
 746     keys[2] = NULL;
 747 
 748     /* if provided, add any other value */
 749     if (NULL != info_ptr) {
 750         keys[1] = info_ptr->key;
 751     }
 752 
 753     rc = PMIx_Unpublish(keys, NULL, 0);
 754     return convert_err(rc);
 755 }
 756 
 757 /****    CONVERSION ROUTINES    ****/
 758 static pmix_status_t convert_int(int *value, pmix_value_t *kv)
 759 {
 760     switch(kv->type) {
 761     case PMIX_INT:
 762         *value = kv->data.integer;
 763         break;
 764     case PMIX_INT8:
 765         *value = kv->data.int8;
 766         break;
 767     case PMIX_INT16:
 768         *value = kv->data.int16;
 769         break;
 770     case PMIX_INT32:
 771         *value = kv->data.int32;
 772         break;
 773     case PMIX_INT64:
 774         *value = kv->data.int64;
 775         break;
 776     case PMIX_UINT:
 777         *value = kv->data.uint;
 778         break;
 779     case PMIX_UINT8:
 780         *value = kv->data.uint8;
 781         break;
 782     case PMIX_UINT16:
 783         *value = kv->data.uint16;
 784         break;
 785     case PMIX_UINT32:
 786         *value = kv->data.uint32;
 787         break;
 788     case PMIX_UINT64:
 789         *value = kv->data.uint64;
 790         break;
 791     case PMIX_BYTE:
 792         *value = kv->data.byte;
 793         break;
 794     case PMIX_SIZE:
 795         *value = kv->data.size;
 796         break;
 797     case PMIX_BOOL:
 798         *value = kv->data.flag;
 799         break;
 800     default:
 801         /* not an integer type */
 802         return PMIX_ERR_BAD_PARAM;
 803     }
 804     return PMIX_SUCCESS;
 805 }
 806 
 807 static int convert_err(pmix_status_t rc)
 808 {
 809     switch(rc) {
 810     case PMIX_ERR_INVALID_SIZE:
 811         return PMI2_ERR_INVALID_SIZE;
 812 
 813     case PMIX_ERR_INVALID_KEYVALP:
 814         return PMI2_ERR_INVALID_KEYVALP;
 815 
 816     case PMIX_ERR_INVALID_NUM_PARSED:
 817         return PMI2_ERR_INVALID_NUM_PARSED;
 818 
 819     case PMIX_ERR_INVALID_ARGS:
 820         return PMI2_ERR_INVALID_ARGS;
 821 
 822     case PMIX_ERR_INVALID_NUM_ARGS:
 823         return PMI2_ERR_INVALID_NUM_ARGS;
 824 
 825     case PMIX_ERR_INVALID_LENGTH:
 826         return PMI2_ERR_INVALID_LENGTH;
 827 
 828     case PMIX_ERR_INVALID_VAL_LENGTH:
 829         return PMI2_ERR_INVALID_VAL_LENGTH;
 830 
 831     case PMIX_ERR_INVALID_VAL:
 832         return PMI2_ERR_INVALID_VAL;
 833 
 834     case PMIX_ERR_INVALID_KEY_LENGTH:
 835         return PMI2_ERR_INVALID_KEY_LENGTH;
 836 
 837     case PMIX_ERR_INVALID_KEY:
 838         return PMI2_ERR_INVALID_KEY;
 839 
 840     case PMIX_ERR_INVALID_ARG:
 841         return PMI2_ERR_INVALID_ARG;
 842 
 843     case PMIX_ERR_NOMEM:
 844         return PMI2_ERR_NOMEM;
 845 
 846     case PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER:
 847     case PMIX_ERR_LOST_CONNECTION_TO_SERVER:
 848     case PMIX_ERR_LOST_PEER_CONNECTION:
 849     case PMIX_ERR_LOST_CONNECTION_TO_CLIENT:
 850     case PMIX_ERR_NOT_SUPPORTED:
 851     case PMIX_ERR_NOT_FOUND:
 852     case PMIX_ERR_SERVER_NOT_AVAIL:
 853     case PMIX_ERR_INVALID_NAMESPACE:
 854     case PMIX_ERR_DATA_VALUE_NOT_FOUND:
 855     case PMIX_ERR_OUT_OF_RESOURCE:
 856     case PMIX_ERR_RESOURCE_BUSY:
 857     case PMIX_ERR_BAD_PARAM:
 858     case PMIX_ERR_IN_ERRNO:
 859     case PMIX_ERR_UNREACH:
 860     case PMIX_ERR_TIMEOUT:
 861     case PMIX_ERR_NO_PERMISSIONS:
 862     case PMIX_ERR_PACK_MISMATCH:
 863     case PMIX_ERR_PACK_FAILURE:
 864     case PMIX_ERR_UNPACK_FAILURE:
 865     case PMIX_ERR_UNPACK_INADEQUATE_SPACE:
 866     case PMIX_ERR_TYPE_MISMATCH:
 867     case PMIX_ERR_PROC_ENTRY_NOT_FOUND:
 868     case PMIX_ERR_UNKNOWN_DATA_TYPE:
 869     case PMIX_ERR_WOULD_BLOCK:
 870     case PMIX_EXISTS:
 871     case PMIX_ERROR:
 872         return PMI2_FAIL;
 873 
 874     case PMIX_ERR_INIT:
 875         return PMI2_ERR_INIT;
 876 
 877     case PMIX_SUCCESS:
 878         return PMI2_SUCCESS;
 879     default:
 880         return PMI2_FAIL;
 881     }
 882 }

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