root/opal/mca/pmix/ext3x/ext3x.c

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

DEFINITIONS

This source file includes following definitions.
  1. legacy_get
  2. opcbfunc
  3. ext3x_get_nspace
  4. ext3x_register_jobid
  5. event_hdlr_complete
  6. return_local_event_hdlr
  7. process_event
  8. ext3x_event_hdlr
  9. ext3x_register_cleanup
  10. ext3x_convert_rank
  11. ext3x_convert_opalrank
  12. ext3x_convert_opalrc
  13. ext3x_convert_rc
  14. ext3x_convert_scope
  15. ext3x_convert_opalscope
  16. ext3x_convert_opalrange
  17. ext3x_convert_range
  18. ext3x_convert_persist
  19. ext3x_convert_opalpersist
  20. ext3x_convert_jobid
  21. ext3x_value_load
  22. ext3x_value_unload
  23. errreg_cbfunc
  24. register_handler
  25. deregister_handler
  26. notify_complete
  27. notify_event
  28. relcbfunc
  29. infocbfunc
  30. ext3x_query
  31. ext3x_log
  32. ext3x_convert_allocdir
  33. ext3x_convert_state
  34. ext3x_convert_opalstate
  35. evcon
  36. evdes
  37. opcon
  38. opdes
  39. ocadcon
  40. ocaddes
  41. tscon
  42. tsdes
  43. dmcon
  44. dmdes

   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) 2014-2019 Research Organization for Information Science
   5  *                         and Technology (RIST).  All rights reserved.
   6  * Copyright (c) 2014-2015 Mellanox Technologies, Inc.
   7  *                         All rights reserved.
   8  * Copyright (c) 2016      Cisco Systems, Inc.  All rights reserved.
   9  * Copyright (c) 2017      Los Alamos National Security, LLC. All rights
  10  *                         reserved.
  11  * $COPYRIGHT$
  12  *
  13  * Additional copyrights may follow
  14  *
  15  * $HEADER$
  16  */
  17 
  18 #include "opal_config.h"
  19 #include "opal/constants.h"
  20 #include "opal/types.h"
  21 
  22 #ifdef HAVE_STRING_H
  23 #include <string.h>
  24 #endif
  25 #ifdef HAVE_UNISTD_H
  26 #include <unistd.h>
  27 #endif
  28 #ifdef HAVE_SYS_STAT_H
  29 #include <sys/stat.h>
  30 #endif
  31 
  32 #include "opal/dss/dss.h"
  33 #include "opal/mca/event/event.h"
  34 #include "opal/mca/hwloc/base/base.h"
  35 #include "opal/runtime/opal.h"
  36 #include "opal/runtime/opal_progress_threads.h"
  37 #include "opal/threads/threads.h"
  38 #include "opal/util/argv.h"
  39 #include "opal/util/error.h"
  40 #include "opal/util/opal_environ.h"
  41 #include "opal/util/output.h"
  42 #include "opal/util/proc.h"
  43 #include "opal/util/show_help.h"
  44 #include "opal/util/string_copy.h"
  45 
  46 #include "ext3x.h"
  47 #include "opal/mca/pmix/base/base.h"
  48 #include "opal/mca/pmix/pmix_types.h"
  49 
  50 #include <pmix_common.h>
  51 #include <pmix.h>
  52 
  53 /****    C.O.M.M.O.N   I.N.T.E.R.F.A.C.E.S     ****/
  54 
  55 /* These are functions used by both client and server to
  56  * access common functions in the embedded PMIx library */
  57 static bool legacy_get(void);
  58 static const char *ext3x_get_nspace(opal_jobid_t jobid);
  59 static void ext3x_register_jobid(opal_jobid_t jobid, const char *nspace);
  60 static void register_handler(opal_list_t *event_codes,
  61                              opal_list_t *info,
  62                              opal_pmix_notification_fn_t evhandler,
  63                              opal_pmix_evhandler_reg_cbfunc_t cbfunc,
  64                              void *cbdata);
  65 static void deregister_handler(size_t evhandler,
  66                                opal_pmix_op_cbfunc_t cbfunc,
  67                                void *cbdata);
  68 static int notify_event(int status,
  69                         const opal_process_name_t *source,
  70                         opal_pmix_data_range_t range,
  71                         opal_list_t *info,
  72                         opal_pmix_op_cbfunc_t cbfunc, void *cbdata);
  73 static void ext3x_query(opal_list_t *queries,
  74                          opal_pmix_info_cbfunc_t cbfunc, void *cbdata);
  75 static void ext3x_log(opal_list_t *info,
  76                        opal_pmix_op_cbfunc_t cbfunc, void *cbdata);
  77 
  78 static int ext3x_register_cleanup(char *path, bool directory, bool ignore, bool jobscope);
  79 
  80 const opal_pmix_base_module_t opal_pmix_ext3x_module = {
  81     .legacy_get = legacy_get,
  82     /* client APIs */
  83     .init = ext3x_client_init,
  84     .finalize = ext3x_client_finalize,
  85     .initialized = ext3x_initialized,
  86     .abort = ext3x_abort,
  87     .commit = ext3x_commit,
  88     .fence = ext3x_fence,
  89     .fence_nb = ext3x_fencenb,
  90     .put = ext3x_put,
  91     .get = ext3x_get,
  92     .get_nb = ext3x_getnb,
  93     .publish = ext3x_publish,
  94     .publish_nb = ext3x_publishnb,
  95     .lookup = ext3x_lookup,
  96     .lookup_nb = ext3x_lookupnb,
  97     .unpublish = ext3x_unpublish,
  98     .unpublish_nb = ext3x_unpublishnb,
  99     .spawn = ext3x_spawn,
 100     .spawn_nb = ext3x_spawnnb,
 101     .connect = ext3x_connect,
 102     .connect_nb = ext3x_connectnb,
 103     .disconnect = ext3x_disconnect,
 104     .disconnect_nb = ext3x_disconnectnb,
 105     .resolve_peers = ext3x_resolve_peers,
 106     .resolve_nodes = ext3x_resolve_nodes,
 107     .query = ext3x_query,
 108     .log = ext3x_log,
 109     .allocate = ext3x_allocate,
 110     .job_control = ext3x_job_control,
 111     .register_cleanup = ext3x_register_cleanup,
 112     /* server APIs */
 113     .server_init = ext3x_server_init,
 114     .server_finalize = ext3x_server_finalize,
 115     .generate_regex = ext3x_server_gen_regex,
 116     .generate_ppn = ext3x_server_gen_ppn,
 117     .server_register_nspace = ext3x_server_register_nspace,
 118     .server_deregister_nspace = ext3x_server_deregister_nspace,
 119     .server_register_client = ext3x_server_register_client,
 120     .server_deregister_client = ext3x_server_deregister_client,
 121     .server_setup_fork = ext3x_server_setup_fork,
 122     .server_dmodex_request = ext3x_server_dmodex,
 123     .server_notify_event = ext3x_server_notify_event,
 124     .server_iof_push = ext3x_server_iof_push,
 125     .server_setup_application = ext3x_server_setup_application,
 126     .server_setup_local_support = ext3x_server_setup_local_support,
 127     /* tool APIs */
 128     .tool_init = ext3x_tool_init,
 129     .tool_finalize = ext3x_tool_fini,
 130     /* utility APIs */
 131     .get_version = PMIx_Get_version,
 132     .register_evhandler = register_handler,
 133     .deregister_evhandler = deregister_handler,
 134     .notify_event = notify_event,
 135     .store_local = ext3x_store_local,
 136     .get_nspace = ext3x_get_nspace,
 137     .register_jobid = ext3x_register_jobid
 138 };
 139 
 140 static bool legacy_get(void)
 141 {
 142     return false;
 143 }
 144 
 145 static void opcbfunc(pmix_status_t status, void *cbdata)
 146 {
 147     ext3x_opcaddy_t *op = (ext3x_opcaddy_t*)cbdata;
 148 
 149     OPAL_ACQUIRE_OBJECT(op);
 150 
 151     if (NULL != op->opcbfunc) {
 152         op->opcbfunc(ext3x_convert_rc(status), op->cbdata);
 153     }
 154     OBJ_RELEASE(op);
 155 }
 156 
 157 
 158 static const char *ext3x_get_nspace(opal_jobid_t jobid)
 159 {
 160     opal_ext3x_jobid_trkr_t *jptr;
 161 
 162     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 163 
 164     OPAL_LIST_FOREACH(jptr, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
 165         if (jptr->jobid == jobid) {
 166             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 167             return jptr->nspace;
 168         }
 169     }
 170     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 171     return NULL;
 172 }
 173 
 174 static void ext3x_register_jobid(opal_jobid_t jobid, const char *nspace)
 175 {
 176     opal_ext3x_jobid_trkr_t *jptr;
 177 
 178     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 179 
 180     /* if we don't already have it, add this to our jobid tracker */
 181     OPAL_LIST_FOREACH(jptr, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
 182         if (jptr->jobid == jobid) {
 183             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 184             return;
 185         }
 186     }
 187     jptr = OBJ_NEW(opal_ext3x_jobid_trkr_t);
 188     (void)opal_string_copy(jptr->nspace, nspace, PMIX_MAX_NSLEN);
 189     jptr->jobid = jobid;
 190     opal_list_append(&mca_pmix_ext3x_component.jobids, &jptr->super);
 191     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 192 }
 193 
 194 static void event_hdlr_complete(pmix_status_t status, void *cbdata)
 195 {
 196     ext3x_opcaddy_t *op = (ext3x_opcaddy_t*)cbdata;
 197 
 198     OBJ_RELEASE(op);
 199 }
 200 
 201 static void return_local_event_hdlr(int status, opal_list_t *results,
 202                                     opal_pmix_op_cbfunc_t cbfunc, void *thiscbdata,
 203                                     void *notification_cbdata)
 204 {
 205     ext3x_threadshift_t *cd = (ext3x_threadshift_t*)notification_cbdata;
 206     ext3x_opcaddy_t *op;
 207     opal_value_t *kv;
 208     pmix_status_t pstatus;
 209     size_t n;
 210 
 211     OPAL_ACQUIRE_OBJECT(cd);
 212     if (NULL != cd->pmixcbfunc) {
 213         op = OBJ_NEW(ext3x_opcaddy_t);
 214 
 215         if (NULL != results && 0 < (op->ninfo = opal_list_get_size(results))) {
 216             /* convert the list of results to an array of info */
 217             PMIX_INFO_CREATE(op->info, op->ninfo);
 218             n=0;
 219             OPAL_LIST_FOREACH(kv, cd->info, opal_value_t) {
 220                 (void)opal_string_copy(op->info[n].key, kv->key, PMIX_MAX_KEYLEN);
 221                 ext3x_value_load(&op->info[n].value, kv);
 222                 ++n;
 223             }
 224         }
 225         /* convert the status */
 226         pstatus = ext3x_convert_opalrc(status);
 227         /* call the library's callback function */
 228         cd->pmixcbfunc(pstatus, op->info, op->ninfo, event_hdlr_complete, op, cd->cbdata);
 229     }
 230 
 231     /* release the threadshift object */
 232     if (NULL != cd->info) {
 233         OPAL_LIST_RELEASE(cd->info);
 234     }
 235     OBJ_RELEASE(cd);
 236 
 237     /* release the caller */
 238     if (NULL != cbfunc) {
 239         cbfunc(OPAL_SUCCESS, thiscbdata);
 240     }
 241 }
 242 
 243 /* process the notification */
 244 static void process_event(int sd, short args, void *cbdata)
 245 {
 246     ext3x_threadshift_t *cd = (ext3x_threadshift_t*)cbdata;
 247     opal_ext3x_event_t *event;
 248 
 249     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 250 
 251     /* cycle thru the registrations */
 252     OPAL_LIST_FOREACH(event, &mca_pmix_ext3x_component.events, opal_ext3x_event_t) {
 253         if (cd->id == event->index) {
 254             /* found it - invoke the handler, pointing its
 255              * callback function to our callback function */
 256             opal_output_verbose(2, opal_pmix_base_framework.framework_output,
 257                                 "%s _EVENT_HDLR CALLING EVHDLR",
 258                                 OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
 259             if (NULL != event->handler) {
 260                 OBJ_RETAIN(event);
 261                 OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 262                 event->handler(cd->status, &cd->pname,
 263                                cd->info, &cd->results,
 264                                return_local_event_hdlr, cd);
 265                 OBJ_RELEASE(event);
 266                 return;
 267             }
 268         }
 269     }
 270 
 271     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 272 
 273     /* if we didn't find a match, we still have to call their final callback */
 274     if (NULL != cd->pmixcbfunc) {
 275         cd->pmixcbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cd->cbdata);
 276     }
 277     OPAL_LIST_RELEASE(cd->info);
 278     OBJ_RELEASE(cd);
 279     return;
 280 
 281 }
 282 /* this function will be called by the PMIx client library
 283  * whenever it receives notification of an event. The
 284  * notification can come from an ORTE daemon (when launched
 285  * by mpirun), directly from a RM (when direct launched), or
 286  * from another process (via the local daemon).
 287  * The call will occur in the PMIx event base */
 288 void ext3x_event_hdlr(size_t evhdlr_registration_id,
 289                        pmix_status_t status, const pmix_proc_t *source,
 290                        pmix_info_t info[], size_t ninfo,
 291                        pmix_info_t results[], size_t nresults,
 292                        pmix_event_notification_cbfunc_fn_t cbfunc,
 293                        void *cbdata)
 294 {
 295     ext3x_threadshift_t *cd;
 296     int rc;
 297     opal_value_t *iptr;
 298     size_t n;
 299 
 300     opal_output_verbose(2, opal_pmix_base_framework.framework_output,
 301                         "%s RECEIVED NOTIFICATION OF STATUS %d ON HDLR %lu",
 302                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status,
 303                         (unsigned long)evhdlr_registration_id);
 304 
 305     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 306 
 307     cd = OBJ_NEW(ext3x_threadshift_t);
 308     cd->id = evhdlr_registration_id;
 309     cd->pmixcbfunc = cbfunc;
 310     cd->cbdata = cbdata;
 311 
 312     /* convert the incoming status */
 313     cd->status = ext3x_convert_rc(status);
 314     opal_output_verbose(2, opal_pmix_base_framework.framework_output,
 315                         "%s CONVERTED STATUS %d TO STATUS %d",
 316                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), status, cd->status);
 317 
 318     /* convert the nspace/rank to an opal_process_name_t */
 319     if (NULL == source) {
 320         cd->pname.jobid = OPAL_NAME_INVALID->jobid;
 321         cd->pname.vpid = OPAL_NAME_INVALID->vpid;
 322     } else {
 323         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&cd->pname.jobid, source->nspace))) {
 324             OPAL_ERROR_LOG(rc);
 325             cd->pname.jobid = OPAL_NAME_INVALID->jobid;
 326         }
 327         cd->pname.vpid = ext3x_convert_rank(source->rank);
 328     }
 329 
 330     /* convert the array of info */
 331     if (NULL != info) {
 332         cd->info = OBJ_NEW(opal_list_t);
 333         for (n=0; n < ninfo; n++) {
 334             iptr = OBJ_NEW(opal_value_t);
 335             iptr->key = strdup(info[n].key);
 336             if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
 337                 OPAL_ERROR_LOG(rc);
 338                 OBJ_RELEASE(iptr);
 339                 continue;
 340             }
 341             opal_list_append(cd->info, &iptr->super);
 342         }
 343     }
 344 
 345     /* convert the array of prior results */
 346     if (NULL != results) {
 347         for (n=0; n < nresults; n++) {
 348             iptr = OBJ_NEW(opal_value_t);
 349             iptr->key = strdup(results[n].key);
 350             if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &results[n].value))) {
 351                 OPAL_ERROR_LOG(rc);
 352                 OBJ_RELEASE(iptr);
 353                 continue;
 354             }
 355             opal_list_append(&cd->results, &iptr->super);
 356         }
 357     }
 358 
 359     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 360 
 361     /* do NOT directly call the event handler as this
 362      * may lead to a deadlock condition should the
 363      * handler invoke a PMIx function */
 364     OPAL_PMIX2X_THREADSHIFT(cd, process_event);
 365     return;
 366 }
 367 
 368 static int ext3x_register_cleanup(char *path, bool directory, bool ignore, bool jobscope)
 369 {
 370     pmix_info_t pinfo[3];
 371     size_t n, ninfo=0;
 372     pmix_status_t rc;
 373     int ret;
 374 
 375     if (ignore) {
 376         /* they want this path ignored */
 377         PMIX_INFO_LOAD(&pinfo[ninfo], PMIX_CLEANUP_IGNORE, path, PMIX_STRING);
 378         ++ninfo;
 379     } else {
 380         if (directory) {
 381             PMIX_INFO_LOAD(&pinfo[ninfo], PMIX_REGISTER_CLEANUP_DIR, path, PMIX_STRING);
 382             ++ninfo;
 383             /* recursively cleanup directories */
 384             PMIX_INFO_LOAD(&pinfo[ninfo], PMIX_CLEANUP_RECURSIVE, NULL, PMIX_BOOL);
 385             ++ninfo;
 386         } else {
 387             /* order cleanup of the provided path */
 388             PMIX_INFO_LOAD(&pinfo[ninfo], PMIX_REGISTER_CLEANUP, path, PMIX_STRING);
 389             ++ninfo;
 390         }
 391     }
 392 
 393     /* if they want this applied to the job, then indicate so */
 394     if (jobscope) {
 395         rc = PMIx_Job_control_nb(NULL, 0, pinfo, ninfo, NULL, NULL);
 396     } else {
 397         /* only applies to us */
 398         rc = PMIx_Job_control_nb(&mca_pmix_ext3x_component.myproc, 1, pinfo, ninfo, NULL, NULL);
 399     }
 400     ret = ext3x_convert_rc(rc);
 401     for (n=0; n < ninfo; n++) {
 402         PMIX_INFO_DESTRUCT(&pinfo[n]);
 403     }
 404     return ret;
 405 }
 406 
 407 opal_vpid_t ext3x_convert_rank(pmix_rank_t rank)
 408 {
 409     switch(rank) {
 410     case PMIX_RANK_UNDEF:
 411         return OPAL_VPID_INVALID;
 412     case PMIX_RANK_WILDCARD:
 413         return OPAL_VPID_WILDCARD;
 414     default:
 415         return (opal_vpid_t)rank;
 416     }
 417 }
 418 
 419 pmix_rank_t ext3x_convert_opalrank(opal_vpid_t vpid)
 420 {
 421     switch(vpid) {
 422     case OPAL_VPID_WILDCARD:
 423         return PMIX_RANK_WILDCARD;
 424     case OPAL_VPID_INVALID:
 425         return PMIX_RANK_UNDEF;
 426     default:
 427         return (pmix_rank_t)vpid;
 428     }
 429 }
 430 
 431 pmix_status_t ext3x_convert_opalrc(int rc)
 432 {
 433     switch (rc) {
 434     case OPAL_ERR_DEBUGGER_RELEASE:
 435         return PMIX_ERR_DEBUGGER_RELEASE;
 436 
 437     case OPAL_ERR_HANDLERS_COMPLETE:
 438         return PMIX_EVENT_ACTION_COMPLETE;
 439 
 440     case OPAL_ERR_PROC_ABORTED:
 441         return PMIX_ERR_PROC_ABORTED;
 442 
 443     case OPAL_ERR_PROC_REQUESTED_ABORT:
 444         return PMIX_ERR_PROC_REQUESTED_ABORT;
 445 
 446     case OPAL_ERR_PROC_ABORTING:
 447         return PMIX_ERR_PROC_ABORTING;
 448 
 449     case OPAL_ERR_NODE_DOWN:
 450         return PMIX_ERR_NODE_DOWN;
 451 
 452     case OPAL_ERR_NODE_OFFLINE:
 453         return PMIX_ERR_NODE_OFFLINE;
 454 
 455     case OPAL_ERR_JOB_TERMINATED:
 456         return PMIX_ERR_JOB_TERMINATED;
 457 
 458     case OPAL_ERR_PROC_RESTART:
 459         return PMIX_ERR_PROC_RESTART;
 460 
 461     case OPAL_ERR_PROC_CHECKPOINT:
 462         return PMIX_ERR_PROC_CHECKPOINT;
 463 
 464     case OPAL_ERR_PROC_MIGRATE:
 465         return PMIX_ERR_PROC_MIGRATE;
 466 
 467     case OPAL_ERR_EVENT_REGISTRATION:
 468         return PMIX_ERR_EVENT_REGISTRATION;
 469 
 470     case OPAL_ERR_NOT_IMPLEMENTED:
 471     case OPAL_ERR_NOT_SUPPORTED:
 472         return PMIX_ERR_NOT_SUPPORTED;
 473 
 474     case OPAL_ERR_NOT_FOUND:
 475         return PMIX_ERR_NOT_FOUND;
 476 
 477     case OPAL_ERR_PERM:
 478     case OPAL_ERR_UNREACH:
 479     case OPAL_ERR_SERVER_NOT_AVAIL:
 480         return PMIX_ERR_UNREACH;
 481 
 482     case OPAL_ERR_BAD_PARAM:
 483         return PMIX_ERR_BAD_PARAM;
 484 
 485     case OPAL_ERR_OUT_OF_RESOURCE:
 486         return PMIX_ERR_OUT_OF_RESOURCE;
 487 
 488     case OPAL_ERR_DATA_VALUE_NOT_FOUND:
 489         return PMIX_ERR_DATA_VALUE_NOT_FOUND;
 490 
 491     case OPAL_ERR_TIMEOUT:
 492         return PMIX_ERR_TIMEOUT;
 493 
 494     case OPAL_ERR_WOULD_BLOCK:
 495         return PMIX_ERR_WOULD_BLOCK;
 496 
 497     case OPAL_EXISTS:
 498         return PMIX_EXISTS;
 499 
 500     case OPAL_ERR_PARTIAL_SUCCESS:
 501         return PMIX_QUERY_PARTIAL_SUCCESS;
 502 
 503     case OPAL_ERR_MODEL_DECLARED:
 504         return PMIX_MODEL_DECLARED;
 505 
 506     case OPAL_ERROR:
 507         return PMIX_ERROR;
 508     case OPAL_SUCCESS:
 509         return PMIX_SUCCESS;
 510 
 511     case OPAL_OPERATION_SUCCEEDED:
 512         return PMIX_OPERATION_SUCCEEDED;
 513 
 514     default:
 515         return rc;
 516     }
 517 }
 518 
 519 int ext3x_convert_rc(pmix_status_t rc)
 520 {
 521     switch (rc) {
 522     case PMIX_ERR_DEBUGGER_RELEASE:
 523         return OPAL_ERR_DEBUGGER_RELEASE;
 524 
 525     case PMIX_EVENT_ACTION_COMPLETE:
 526         return OPAL_ERR_HANDLERS_COMPLETE;
 527 
 528     case PMIX_ERR_PROC_ABORTED:
 529         return OPAL_ERR_PROC_ABORTED;
 530 
 531     case PMIX_ERR_PROC_REQUESTED_ABORT:
 532         return OPAL_ERR_PROC_REQUESTED_ABORT;
 533 
 534     case PMIX_ERR_PROC_ABORTING:
 535         return OPAL_ERR_PROC_ABORTING;
 536 
 537     case PMIX_ERR_NODE_DOWN:
 538         return OPAL_ERR_NODE_DOWN;
 539 
 540     case PMIX_ERR_NODE_OFFLINE:
 541         return OPAL_ERR_NODE_OFFLINE;
 542 
 543     case PMIX_ERR_JOB_TERMINATED:
 544         return OPAL_ERR_JOB_TERMINATED;
 545 
 546     case PMIX_ERR_PROC_RESTART:
 547         return OPAL_ERR_PROC_RESTART;
 548 
 549     case PMIX_ERR_PROC_CHECKPOINT:
 550         return OPAL_ERR_PROC_CHECKPOINT;
 551 
 552     case PMIX_ERR_PROC_MIGRATE:
 553         return OPAL_ERR_PROC_MIGRATE;
 554 
 555     case PMIX_ERR_EVENT_REGISTRATION:
 556         return OPAL_ERR_EVENT_REGISTRATION;
 557 
 558     case PMIX_ERR_NOT_SUPPORTED:
 559         return OPAL_ERR_NOT_SUPPORTED;
 560 
 561     case PMIX_ERR_NOT_FOUND:
 562         return OPAL_ERR_NOT_FOUND;
 563 
 564     case PMIX_ERR_OUT_OF_RESOURCE:
 565         return OPAL_ERR_OUT_OF_RESOURCE;
 566 
 567     case PMIX_ERR_INIT:
 568         return OPAL_ERROR;
 569 
 570     case PMIX_ERR_BAD_PARAM:
 571         return OPAL_ERR_BAD_PARAM;
 572 
 573     case PMIX_ERR_UNREACH:
 574     case PMIX_ERR_NO_PERMISSIONS:
 575         return OPAL_ERR_UNREACH;
 576 
 577     case PMIX_ERR_TIMEOUT:
 578         return OPAL_ERR_TIMEOUT;
 579 
 580     case PMIX_ERR_WOULD_BLOCK:
 581         return OPAL_ERR_WOULD_BLOCK;
 582 
 583     case PMIX_ERR_LOST_CONNECTION_TO_SERVER:
 584     case PMIX_ERR_LOST_PEER_CONNECTION:
 585     case PMIX_ERR_LOST_CONNECTION_TO_CLIENT:
 586         return OPAL_ERR_COMM_FAILURE;
 587 
 588     case PMIX_EXISTS:
 589         return OPAL_EXISTS;
 590 
 591     case PMIX_QUERY_PARTIAL_SUCCESS:
 592         return OPAL_ERR_PARTIAL_SUCCESS;
 593 
 594     case PMIX_MONITOR_HEARTBEAT_ALERT:
 595         return OPAL_ERR_HEARTBEAT_ALERT;
 596 
 597     case PMIX_MONITOR_FILE_ALERT:
 598         return OPAL_ERR_FILE_ALERT;
 599 
 600     case PMIX_MODEL_DECLARED:
 601         return OPAL_ERR_MODEL_DECLARED;
 602 
 603     case PMIX_ERROR:
 604         return OPAL_ERROR;
 605     case PMIX_SUCCESS:
 606         return OPAL_SUCCESS;
 607 
 608     case PMIX_OPERATION_SUCCEEDED:
 609         return OPAL_OPERATION_SUCCEEDED;
 610 
 611     default:
 612         return rc;
 613     }
 614 }
 615 
 616 opal_pmix_scope_t ext3x_convert_scope(pmix_scope_t scope)
 617 {
 618     switch(scope) {
 619         case PMIX_SCOPE_UNDEF:
 620             return OPAL_PMIX_SCOPE_UNDEF;
 621         case PMIX_LOCAL:
 622             return OPAL_PMIX_LOCAL;
 623         case PMIX_REMOTE:
 624             return OPAL_PMIX_REMOTE;
 625         case PMIX_GLOBAL:
 626             return OPAL_PMIX_GLOBAL;
 627         default:
 628             return OPAL_PMIX_SCOPE_UNDEF;
 629     }
 630 }
 631 
 632 pmix_scope_t ext3x_convert_opalscope(opal_pmix_scope_t scope) {
 633     switch(scope) {
 634     case OPAL_PMIX_LOCAL:
 635         return PMIX_LOCAL;
 636     case OPAL_PMIX_REMOTE:
 637         return PMIX_REMOTE;
 638     case OPAL_PMIX_GLOBAL:
 639         return PMIX_GLOBAL;
 640     default:
 641         return PMIX_SCOPE_UNDEF;
 642     }
 643 }
 644 
 645 pmix_data_range_t ext3x_convert_opalrange(opal_pmix_data_range_t range) {
 646     switch(range) {
 647     case OPAL_PMIX_RANGE_UNDEF:
 648         return PMIX_RANGE_UNDEF;
 649     case OPAL_PMIX_RANGE_LOCAL:
 650         return PMIX_RANGE_LOCAL;
 651     case OPAL_PMIX_RANGE_NAMESPACE:
 652         return PMIX_RANGE_NAMESPACE;
 653     case OPAL_PMIX_RANGE_SESSION:
 654         return PMIX_RANGE_SESSION;
 655     case OPAL_PMIX_RANGE_GLOBAL:
 656         return PMIX_RANGE_GLOBAL;
 657     case OPAL_PMIX_RANGE_CUSTOM:
 658         return PMIX_RANGE_CUSTOM;
 659     case OPAL_PMIX_RANGE_PROC_LOCAL:
 660         return PMIX_RANGE_PROC_LOCAL;
 661     default:
 662         return PMIX_SCOPE_UNDEF;
 663     }
 664 }
 665 
 666 opal_pmix_data_range_t ext3x_convert_range(pmix_data_range_t range) {
 667     switch(range) {
 668     case PMIX_RANGE_UNDEF:
 669         return OPAL_PMIX_RANGE_UNDEF;
 670     case PMIX_RANGE_LOCAL:
 671         return OPAL_PMIX_RANGE_LOCAL;
 672     case PMIX_RANGE_NAMESPACE:
 673         return OPAL_PMIX_RANGE_NAMESPACE;
 674     case PMIX_RANGE_SESSION:
 675         return OPAL_PMIX_RANGE_SESSION;
 676     case PMIX_RANGE_GLOBAL:
 677         return OPAL_PMIX_RANGE_GLOBAL;
 678     case PMIX_RANGE_CUSTOM:
 679         return OPAL_PMIX_RANGE_CUSTOM;
 680     default:
 681         return OPAL_PMIX_RANGE_UNDEF;
 682     }
 683 }
 684 
 685 opal_pmix_persistence_t ext3x_convert_persist(pmix_persistence_t persist)
 686 {
 687     switch(persist) {
 688         case PMIX_PERSIST_INDEF:
 689             return OPAL_PMIX_PERSIST_INDEF;
 690         case PMIX_PERSIST_FIRST_READ:
 691             return OPAL_PMIX_PERSIST_FIRST_READ;
 692         case PMIX_PERSIST_PROC:
 693             return OPAL_PMIX_PERSIST_PROC;
 694         case PMIX_PERSIST_APP:
 695             return OPAL_PMIX_PERSIST_APP;
 696         case PMIX_PERSIST_SESSION:
 697             return OPAL_PMIX_PERSIST_SESSION;
 698         default:
 699         return OPAL_PMIX_PERSIST_INDEF;
 700     }
 701 }
 702 
 703 pmix_persistence_t ext3x_convert_opalpersist(opal_pmix_persistence_t persist)
 704 {
 705     switch(persist) {
 706         case OPAL_PMIX_PERSIST_INDEF:
 707             return PMIX_PERSIST_INDEF;
 708         case OPAL_PMIX_PERSIST_FIRST_READ:
 709             return PMIX_PERSIST_FIRST_READ;
 710         case OPAL_PMIX_PERSIST_PROC:
 711             return PMIX_PERSIST_PROC;
 712         case OPAL_PMIX_PERSIST_APP:
 713             return PMIX_PERSIST_APP;
 714         case OPAL_PMIX_PERSIST_SESSION:
 715             return PMIX_PERSIST_SESSION;
 716         default:
 717             return PMIX_PERSIST_INDEF;
 718     }
 719 }
 720 
 721 char* ext3x_convert_jobid(opal_jobid_t jobid)
 722 {
 723     opal_ext3x_jobid_trkr_t *jptr;
 724 
 725     /* look thru our list of jobids and find the
 726      * corresponding nspace */
 727     OPAL_LIST_FOREACH(jptr, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
 728         if (jptr->jobid == jobid) {
 729             return jptr->nspace;
 730         }
 731     }
 732     return NULL;
 733 }
 734 
 735 /****   RHC: NEED TO ADD SUPPORT FOR NEW PMIX DATA TYPES, INCLUDING
 736  ****   CONVERSION OF PROC STATES    ****/
 737 
 738 void ext3x_value_load(pmix_value_t *v,
 739                        opal_value_t *kv)
 740 {
 741     opal_ext3x_jobid_trkr_t *job;
 742     bool found;
 743     opal_list_t *list;
 744     opal_value_t *val;
 745     pmix_info_t *info;
 746     size_t n;
 747 
 748     switch(kv->type) {
 749         case OPAL_UNDEF:
 750             v->type = PMIX_UNDEF;
 751             break;
 752         case OPAL_BOOL:
 753             v->type = PMIX_BOOL;
 754             memcpy(&(v->data.flag), &kv->data.flag, 1);
 755             break;
 756         case OPAL_BYTE:
 757             v->type = PMIX_BYTE;
 758             memcpy(&(v->data.byte), &kv->data.byte, 1);
 759             break;
 760         case OPAL_STRING:
 761             v->type = PMIX_STRING;
 762             if (NULL != kv->data.string) {
 763                 v->data.string = strdup(kv->data.string);
 764             } else {
 765                 v->data.string = NULL;
 766             }
 767             break;
 768         case OPAL_SIZE:
 769             v->type = PMIX_SIZE;
 770             memcpy(&(v->data.size), &kv->data.size, sizeof(size_t));
 771             break;
 772         case OPAL_PID:
 773             v->type = PMIX_PID;
 774             memcpy(&(v->data.pid), &kv->data.pid, sizeof(pid_t));
 775             break;
 776         case OPAL_INT:
 777             v->type = PMIX_INT;
 778             memcpy(&(v->data.integer), &kv->data.integer, sizeof(int));
 779             break;
 780         case OPAL_INT8:
 781             v->type = PMIX_INT8;
 782             memcpy(&(v->data.int8), &kv->data.int8, 1);
 783             break;
 784         case OPAL_INT16:
 785             v->type = PMIX_INT16;
 786             memcpy(&(v->data.int16), &kv->data.int16, 2);
 787             break;
 788         case OPAL_INT32:
 789             v->type = PMIX_INT32;
 790             memcpy(&(v->data.int32), &kv->data.int32, 4);
 791             break;
 792         case OPAL_INT64:
 793             v->type = PMIX_INT64;
 794             memcpy(&(v->data.int64), &kv->data.int64, 8);
 795             break;
 796         case OPAL_UINT:
 797             v->type = PMIX_UINT;
 798             memcpy(&(v->data.uint), &kv->data.uint, sizeof(int));
 799             break;
 800         case OPAL_UINT8:
 801             v->type = PMIX_UINT8;
 802             memcpy(&(v->data.uint8), &kv->data.uint8, 1);
 803             break;
 804         case OPAL_UINT16:
 805             v->type = PMIX_UINT16;
 806             memcpy(&(v->data.uint16), &kv->data.uint16, 2);
 807             break;
 808         case OPAL_UINT32:
 809             v->type = PMIX_UINT32;
 810             memcpy(&(v->data.uint32), &kv->data.uint32, 4);
 811             break;
 812         case OPAL_UINT64:
 813             v->type = PMIX_UINT64;
 814             memcpy(&(v->data.uint64), &kv->data.uint64, 8);
 815             break;
 816         case OPAL_FLOAT:
 817             v->type = PMIX_FLOAT;
 818             memcpy(&(v->data.fval), &kv->data.fval, sizeof(float));
 819             break;
 820         case OPAL_DOUBLE:
 821             v->type = PMIX_DOUBLE;
 822             memcpy(&(v->data.dval), &kv->data.dval, sizeof(double));
 823             break;
 824         case OPAL_TIMEVAL:
 825             v->type = PMIX_TIMEVAL;
 826             memcpy(&(v->data.tv), &kv->data.tv, sizeof(struct timeval));
 827             break;
 828         case OPAL_TIME:
 829             v->type = PMIX_TIME;
 830             memcpy(&(v->data.time), &kv->data.time, sizeof(time_t));
 831             break;
 832         case OPAL_STATUS:
 833             v->type = PMIX_STATUS;
 834             v->data.status = ext3x_convert_opalrc(kv->data.status);
 835             break;
 836         case OPAL_VPID:
 837             v->type = PMIX_PROC_RANK;
 838             v->data.rank = ext3x_convert_opalrank(kv->data.name.vpid);
 839             break;
 840         case OPAL_NAME:
 841             v->type = PMIX_PROC;
 842             /* have to stringify the jobid */
 843             PMIX_PROC_CREATE(v->data.proc, 1);
 844             /* see if this job is in our list of known nspaces */
 845             found = false;
 846             OPAL_LIST_FOREACH(job, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
 847                 if (job->jobid == kv->data.name.jobid) {
 848                     (void)opal_string_copy(v->data.proc->nspace, job->nspace, PMIX_MAX_NSLEN);
 849                     found = true;
 850                     break;
 851                 }
 852             }
 853             if (!found) {
 854                 (void)opal_snprintf_jobid(v->data.proc->nspace, PMIX_MAX_NSLEN, kv->data.name.jobid);
 855             }
 856             v->data.proc->rank = ext3x_convert_opalrank(kv->data.name.vpid);
 857             break;
 858         case OPAL_BYTE_OBJECT:
 859             v->type = PMIX_BYTE_OBJECT;
 860             if (NULL != kv->data.bo.bytes) {
 861                 v->data.bo.bytes = (char*)malloc(kv->data.bo.size);
 862                 memcpy(v->data.bo.bytes, kv->data.bo.bytes, kv->data.bo.size);
 863                 v->data.bo.size = (size_t)kv->data.bo.size;
 864             } else {
 865                 v->data.bo.bytes = NULL;
 866                 v->data.bo.size = 0;
 867             }
 868             break;
 869         case OPAL_PERSIST:
 870             v->type = PMIX_PERSIST;
 871             v->data.persist = ext3x_convert_opalpersist((opal_pmix_persistence_t)kv->data.uint8);
 872             break;
 873         case OPAL_SCOPE:
 874             v->type = PMIX_SCOPE;
 875             v->data.scope = ext3x_convert_opalscope((opal_pmix_scope_t)kv->data.uint8);
 876             break;
 877         case OPAL_DATA_RANGE:
 878             v->type = PMIX_DATA_RANGE;
 879             v->data.range = ext3x_convert_opalrange((opal_pmix_data_range_t)kv->data.uint8);
 880             break;
 881         case OPAL_PROC_STATE:
 882             v->type = PMIX_PROC_STATE;
 883             /* the OPAL layer doesn't have any concept of proc state,
 884              * so the ORTE layer is responsible for converting it */
 885             memcpy(&v->data.state, &kv->data.uint8, sizeof(uint8_t));
 886             break;
 887         case OPAL_PTR:
 888             /* if the opal_value_t is passing a true pointer, then
 889              * respect that request and pass it along */
 890             if (0 == strcmp(kv->key, OPAL_PMIX_EVENT_RETURN_OBJECT)) {
 891                 v->type = PMIX_POINTER;
 892                 v->data.ptr = kv->data.ptr;
 893                 break;
 894             }
 895             /* otherwise, it must be to a list of
 896              * opal_value_t's that we need to convert to a pmix_data_array
 897              * of pmix_info_t structures */
 898             list = (opal_list_t*)kv->data.ptr;
 899             v->type = PMIX_DATA_ARRAY;
 900             v->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t));
 901             v->data.darray->type = PMIX_INFO;
 902             v->data.darray->size = opal_list_get_size(list);
 903             if (0 < v->data.darray->size) {
 904                 PMIX_INFO_CREATE(info, v->data.darray->size);
 905                 v->data.darray->array = info;
 906                 n=0;
 907                 OPAL_LIST_FOREACH(val, list, opal_value_t) {
 908                     if (NULL != val->key) {
 909                         (void)opal_string_copy(info[n].key, val->key, PMIX_MAX_KEYLEN);
 910                     }
 911                     ext3x_value_load(&info[n].value, val);
 912                     ++n;
 913                 }
 914             } else {
 915                 v->data.darray->array = NULL;
 916             }
 917             break;
 918         case OPAL_PROC_INFO:
 919             v->type = PMIX_PROC_INFO;
 920             PMIX_PROC_INFO_CREATE(v->data.pinfo, 1);
 921             /* see if this job is in our list of known nspaces */
 922             found = false;
 923             OPAL_LIST_FOREACH(job, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
 924                 if (job->jobid == kv->data.pinfo.name.jobid) {
 925                     (void)opal_string_copy(v->data.pinfo->proc.nspace, job->nspace, PMIX_MAX_NSLEN);
 926                     found = true;
 927                     break;
 928                 }
 929             }
 930             if (!found) {
 931                 (void)opal_snprintf_jobid(v->data.pinfo->proc.nspace, PMIX_MAX_NSLEN, kv->data.pinfo.name.jobid);
 932             }
 933             v->data.pinfo->proc.rank = ext3x_convert_opalrank(kv->data.pinfo.name.vpid);
 934             if (NULL != kv->data.pinfo.hostname) {
 935                 v->data.pinfo->hostname = strdup(kv->data.pinfo.hostname);
 936             }
 937             if (NULL != kv->data.pinfo.executable_name) {
 938                 v->data.pinfo->executable_name = strdup(kv->data.pinfo.executable_name);
 939             }
 940             v->data.pinfo->pid = kv->data.pinfo.pid;
 941             v->data.pinfo->exit_code = kv->data.pinfo.exit_code;
 942             v->data.pinfo->state = ext3x_convert_opalstate(kv->data.pinfo.state);
 943             break;
 944         case OPAL_ENVAR:
 945             v->type = PMIX_ENVAR;
 946             PMIX_ENVAR_CONSTRUCT(&v->data.envar);
 947             if (NULL != kv->data.envar.envar) {
 948                 v->data.envar.envar = strdup(kv->data.envar.envar);
 949             }
 950             if (NULL != kv->data.envar.value) {
 951                 v->data.envar.value = strdup(kv->data.envar.value);
 952             }
 953             v->data.envar.separator = kv->data.envar.separator;
 954             break;
 955         default:
 956             /* silence warnings */
 957             break;
 958     }
 959 }
 960 
 961 int ext3x_value_unload(opal_value_t *kv,
 962                         const pmix_value_t *v)
 963 {
 964     int rc=OPAL_SUCCESS;
 965     bool found;
 966     opal_ext3x_jobid_trkr_t *job;
 967     opal_list_t *lt;
 968     opal_value_t *ival;
 969     size_t n;
 970 
 971     switch(v->type) {
 972     case PMIX_UNDEF:
 973         kv->type = OPAL_UNDEF;
 974         break;
 975     case PMIX_BOOL:
 976         kv->type = OPAL_BOOL;
 977         memcpy(&kv->data.flag, &(v->data.flag), 1);
 978         break;
 979     case PMIX_BYTE:
 980         kv->type = OPAL_BYTE;
 981         memcpy(&kv->data.byte, &(v->data.byte), 1);
 982         break;
 983     case PMIX_STRING:
 984         kv->type = OPAL_STRING;
 985         if (NULL != v->data.string) {
 986             kv->data.string = strdup(v->data.string);
 987         }
 988         break;
 989     case PMIX_SIZE:
 990         kv->type = OPAL_SIZE;
 991         memcpy(&kv->data.size, &(v->data.size), sizeof(size_t));
 992         break;
 993     case PMIX_PID:
 994         kv->type = OPAL_PID;
 995         memcpy(&kv->data.pid, &(v->data.pid), sizeof(pid_t));
 996         break;
 997     case PMIX_INT:
 998         kv->type = OPAL_INT;
 999         memcpy(&kv->data.integer, &(v->data.integer), sizeof(int));
1000         break;
1001     case PMIX_INT8:
1002         kv->type = OPAL_INT8;
1003         memcpy(&kv->data.int8, &(v->data.int8), 1);
1004         break;
1005     case PMIX_INT16:
1006         kv->type = OPAL_INT16;
1007         memcpy(&kv->data.int16, &(v->data.int16), 2);
1008         break;
1009     case PMIX_INT32:
1010         kv->type = OPAL_INT32;
1011         memcpy(&kv->data.int32, &(v->data.int32), 4);
1012         break;
1013     case PMIX_INT64:
1014         kv->type = OPAL_INT64;
1015         memcpy(&kv->data.int64, &(v->data.int64), 8);
1016         break;
1017     case PMIX_UINT:
1018         kv->type = OPAL_UINT;
1019         memcpy(&kv->data.uint, &(v->data.uint), sizeof(int));
1020         break;
1021     case PMIX_UINT8:
1022         kv->type = OPAL_UINT8;
1023         memcpy(&kv->data.uint8, &(v->data.uint8), 1);
1024         break;
1025     case PMIX_UINT16:
1026         kv->type = OPAL_UINT16;
1027         memcpy(&kv->data.uint16, &(v->data.uint16), 2);
1028         break;
1029     case PMIX_UINT32:
1030         kv->type = OPAL_UINT32;
1031         memcpy(&kv->data.uint32, &(v->data.uint32), 4);
1032         break;
1033     case PMIX_UINT64:
1034         kv->type = OPAL_UINT64;
1035         memcpy(&kv->data.uint64, &(v->data.uint64), 8);
1036         break;
1037     case PMIX_FLOAT:
1038         kv->type = OPAL_FLOAT;
1039         memcpy(&kv->data.fval, &(v->data.fval), sizeof(float));
1040         break;
1041     case PMIX_DOUBLE:
1042         kv->type = OPAL_DOUBLE;
1043         memcpy(&kv->data.dval, &(v->data.dval), sizeof(double));
1044         break;
1045     case PMIX_TIMEVAL:
1046         kv->type = OPAL_TIMEVAL;
1047         memcpy(&kv->data.tv, &(v->data.tv), sizeof(struct timeval));
1048         break;
1049     case PMIX_TIME:
1050         kv->type = OPAL_TIME;
1051         memcpy(&kv->data.time, &(v->data.time), sizeof(time_t));
1052         break;
1053     case PMIX_STATUS:
1054         kv->type = OPAL_STATUS;
1055         kv->data.status = ext3x_convert_rc(v->data.status);
1056         break;
1057     case PMIX_VALUE:
1058         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1059         rc = OPAL_ERR_NOT_SUPPORTED;
1060         break;
1061     case PMIX_PROC:
1062         kv->type = OPAL_NAME;
1063         /* see if this job is in our list of known nspaces */
1064         found = false;
1065         OPAL_LIST_FOREACH(job, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
1066             if (0 == strncmp(job->nspace, v->data.proc->nspace, PMIX_MAX_NSLEN)) {
1067                 kv->data.name.jobid = job->jobid;
1068                 found = true;
1069                 break;
1070             }
1071         }
1072         if (!found) {
1073             if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&kv->data.name.jobid, v->data.proc->nspace))) {
1074                 return ext3x_convert_opalrc(rc);
1075             }
1076         }
1077         kv->data.name.vpid = ext3x_convert_rank(v->data.proc->rank);
1078         break;
1079     case PMIX_APP:
1080         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1081         rc = OPAL_ERR_NOT_SUPPORTED;
1082         break;
1083     case PMIX_INFO:
1084         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1085         rc = OPAL_ERR_NOT_SUPPORTED;
1086         break;
1087     case PMIX_PDATA:
1088         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1089         rc = OPAL_ERR_NOT_SUPPORTED;
1090         break;
1091     case PMIX_BUFFER:
1092     OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1093     rc = OPAL_ERR_NOT_SUPPORTED;
1094     break;
1095     case PMIX_BYTE_OBJECT:
1096         kv->type = OPAL_BYTE_OBJECT;
1097         if (NULL != v->data.bo.bytes && 0 < v->data.bo.size) {
1098             kv->data.bo.bytes = (uint8_t*)malloc(v->data.bo.size);
1099             memcpy(kv->data.bo.bytes, v->data.bo.bytes, v->data.bo.size);
1100             kv->data.bo.size = (int)v->data.bo.size;
1101         } else {
1102             kv->data.bo.bytes = NULL;
1103             kv->data.bo.size = 0;
1104         }
1105         break;
1106     case PMIX_KVAL:
1107         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1108         rc = OPAL_ERR_NOT_SUPPORTED;
1109         break;
1110 #ifdef PMIX_MODEX
1111     case PMIX_MODEX:
1112         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1113         rc = OPAL_ERR_NOT_SUPPORTED;
1114         break;
1115 #endif /* PMIX_MODEX */
1116     case PMIX_PERSIST:
1117         kv->type = OPAL_PERSIST;
1118         kv->data.uint8 = ext3x_convert_persist(v->data.persist);
1119         break;
1120     case PMIX_POINTER:
1121         kv->type = OPAL_PTR;
1122         kv->data.ptr = v->data.ptr;
1123         break;
1124     case PMIX_SCOPE:
1125         kv->type = OPAL_SCOPE;
1126         kv->data.uint8 = ext3x_convert_scope(v->data.scope);
1127         break;
1128     case PMIX_DATA_RANGE:
1129         kv->type = OPAL_DATA_RANGE;
1130         kv->data.uint8 = ext3x_convert_range(v->data.range);
1131         break;
1132     case PMIX_COMMAND:
1133         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1134         rc = OPAL_ERR_NOT_SUPPORTED;
1135         break;
1136     case PMIX_INFO_DIRECTIVES:
1137         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1138         rc = OPAL_ERR_NOT_SUPPORTED;
1139         break;
1140     case PMIX_DATA_TYPE:
1141         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1142         rc = OPAL_ERR_NOT_SUPPORTED;
1143         break;
1144     case PMIX_PROC_STATE:
1145         kv->type = OPAL_PROC_STATE;
1146         /* the OPAL layer doesn't have any concept of proc state,
1147          * so the ORTE layer is responsible for converting it */
1148         memcpy(&kv->data.uint8, &v->data.state, sizeof(uint8_t));
1149         break;
1150     case PMIX_PROC_INFO:
1151         kv->type = OPAL_PROC_INFO;
1152         if (NULL == v->data.pinfo) {
1153             rc = OPAL_ERR_BAD_PARAM;
1154             break;
1155         }
1156         /* see if this job is in our list of known nspaces */
1157         found = false;
1158         OPAL_LIST_FOREACH(job, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
1159             if (0 == strncmp(job->nspace, v->data.pinfo->proc.nspace, PMIX_MAX_NSLEN)) {
1160                 kv->data.pinfo.name.jobid = job->jobid;
1161                 found = true;
1162                 break;
1163             }
1164         }
1165         if (!found) {
1166             if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&kv->data.pinfo.name.jobid, v->data.pinfo->proc.nspace))) {
1167                 return ext3x_convert_opalrc(rc);
1168             }
1169         }
1170         kv->data.pinfo.name.vpid = ext3x_convert_rank(v->data.pinfo->proc.rank);
1171         if (NULL != v->data.pinfo->hostname) {
1172             kv->data.pinfo.hostname = strdup(v->data.pinfo->hostname);
1173         }
1174         if (NULL != v->data.pinfo->executable_name) {
1175             kv->data.pinfo.executable_name = strdup(v->data.pinfo->executable_name);
1176         }
1177         kv->data.pinfo.pid = v->data.pinfo->pid;
1178         kv->data.pinfo.exit_code = v->data.pinfo->exit_code;
1179         kv->data.pinfo.state = ext3x_convert_state(v->data.pinfo->state);
1180         break;
1181     case PMIX_DATA_ARRAY:
1182         if (NULL == v->data.darray || NULL == v->data.darray->array) {
1183             kv->data.ptr = NULL;
1184             break;
1185         }
1186         lt = OBJ_NEW(opal_list_t);
1187         kv->type = OPAL_PTR;
1188         kv->data.ptr = (void*)lt;
1189         for (n=0; n < v->data.darray->size; n++) {
1190             ival = OBJ_NEW(opal_value_t);
1191             opal_list_append(lt, &ival->super);
1192             /* handle the various types */
1193             if (PMIX_INFO == v->data.darray->type) {
1194                 pmix_info_t *iptr = (pmix_info_t*)v->data.darray->array;
1195                 if (NULL == iptr) {
1196                     rc = OPAL_ERR_BAD_PARAM;
1197                     break;
1198                 }
1199                 ival->key = strdup(iptr[n].key);
1200                 rc = ext3x_value_unload(ival, &iptr[n].value);
1201                 if (OPAL_SUCCESS != rc) {
1202                     OPAL_LIST_RELEASE(lt);
1203                     kv->type = OPAL_UNDEF;
1204                     kv->data.ptr = NULL;
1205                     break;
1206                 }
1207             }
1208         }
1209         break;
1210     case PMIX_PROC_RANK:
1211         kv->type = OPAL_VPID;
1212         kv->data.name.vpid = ext3x_convert_rank(v->data.rank);
1213         break;
1214     case PMIX_QUERY:
1215         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1216         rc = OPAL_ERR_NOT_SUPPORTED;
1217         break;
1218     case PMIX_COMPRESSED_STRING:
1219         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1220         rc = OPAL_ERR_NOT_SUPPORTED;
1221         break;
1222     case PMIX_ALLOC_DIRECTIVE:
1223         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1224         rc = OPAL_ERR_NOT_SUPPORTED;
1225         break;
1226 #ifdef PMIX_INFO_ARRAY
1227     case PMIX_INFO_ARRAY:
1228         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1229         rc = OPAL_ERR_NOT_SUPPORTED;
1230         break;
1231 #endif /* PMIX_INFO_ARRAY */
1232     case PMIX_IOF_CHANNEL:
1233         OPAL_ERROR_LOG(OPAL_ERR_NOT_SUPPORTED);
1234         rc = OPAL_ERR_NOT_SUPPORTED;
1235         break;
1236     case PMIX_ENVAR:
1237         kv->type = OPAL_ENVAR;
1238         OBJ_CONSTRUCT(&kv->data.envar, opal_envar_t);
1239         if (NULL != v->data.envar.envar) {
1240             kv->data.envar.envar = strdup(v->data.envar.envar);
1241         }
1242         if (NULL != v->data.envar.value) {
1243             kv->data.envar.value = strdup(v->data.envar.value);
1244         }
1245         kv->data.envar.separator = v->data.envar.separator;
1246         break;
1247     default:
1248         /* silence warnings */
1249         rc = OPAL_ERROR;
1250         break;
1251     }
1252     return rc;
1253 }
1254 
1255 static void errreg_cbfunc (pmix_status_t status,
1256                            size_t errhandler_ref,
1257                            void *cbdata)
1258 {
1259     ext3x_opcaddy_t *op = (ext3x_opcaddy_t*)cbdata;
1260 
1261     OPAL_ACQUIRE_OBJECT(op);
1262     op->event->index = errhandler_ref;
1263     opal_output_verbose(5, opal_pmix_base_framework.framework_output,
1264                         "PMIX3x errreg_cbfunc - error handler registered status=%d, reference=%lu",
1265                         status, (unsigned long)errhandler_ref);
1266     if (NULL != op->evregcbfunc) {
1267         op->evregcbfunc(ext3x_convert_rc(status), errhandler_ref, op->cbdata);
1268     }
1269     OBJ_RELEASE(op);
1270 }
1271 
1272 static void register_handler(opal_list_t *event_codes,
1273                              opal_list_t *info,
1274                              opal_pmix_notification_fn_t evhandler,
1275                              opal_pmix_evhandler_reg_cbfunc_t cbfunc,
1276                              void *cbdata)
1277 {
1278     ext3x_opcaddy_t *op = (ext3x_opcaddy_t*)cbdata;
1279     size_t n;
1280     opal_value_t *kv;
1281 
1282     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1283     if (0 >= opal_pmix_base.initialized) {
1284         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1285         if (NULL != cbfunc) {
1286             cbfunc(OPAL_ERR_NOT_INITIALIZED, 0, cbdata);
1287         }
1288         return;
1289     }
1290 
1291     op = OBJ_NEW(ext3x_opcaddy_t);
1292     op->evregcbfunc = cbfunc;
1293     op->cbdata = cbdata;
1294 
1295     /* convert the event codes */
1296     if (NULL != event_codes) {
1297         op->ncodes = opal_list_get_size(event_codes);
1298         op->pcodes = (pmix_status_t*)malloc(op->ncodes * sizeof(pmix_status_t));
1299         n=0;
1300         OPAL_LIST_FOREACH(kv, event_codes, opal_value_t) {
1301             op->pcodes[n] = ext3x_convert_opalrc(kv->data.integer);
1302             ++n;
1303         }
1304     }
1305 
1306     /* convert the list of info to an array of pmix_info_t */
1307     if (NULL != info && 0 < (op->ninfo = opal_list_get_size(info))) {
1308         PMIX_INFO_CREATE(op->info, op->ninfo);
1309         n=0;
1310         OPAL_LIST_FOREACH(kv, info, opal_value_t) {
1311             (void)opal_string_copy(op->info[n].key, kv->key, PMIX_MAX_KEYLEN);
1312             ext3x_value_load(&op->info[n].value, kv);
1313             ++n;
1314         }
1315     }
1316 
1317     /* register the event */
1318     op->event = OBJ_NEW(opal_ext3x_event_t);
1319     op->event->handler = evhandler;
1320     opal_list_append(&mca_pmix_ext3x_component.events, &op->event->super);
1321     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1322 
1323     PMIx_Register_event_handler(op->pcodes, op->ncodes,
1324                                 op->info, op->ninfo,
1325                                 ext3x_event_hdlr, errreg_cbfunc, op);
1326     return;
1327 }
1328 
1329 static void deregister_handler(size_t evhandler,
1330                                opal_pmix_op_cbfunc_t cbfunc,
1331                                void *cbdata)
1332 {
1333     ext3x_opcaddy_t *op;
1334     opal_ext3x_event_t *event;
1335 
1336     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1337     if (0 >= opal_pmix_base.initialized) {
1338         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1339         if (NULL != cbfunc) {
1340             cbfunc(OPAL_ERR_NOT_INITIALIZED, cbdata);
1341         }
1342         return;
1343     }
1344 
1345     /* look for this event */
1346     OPAL_LIST_FOREACH(event, &mca_pmix_ext3x_component.events, opal_ext3x_event_t) {
1347         if (evhandler == event->index) {
1348             opal_list_remove_item(&mca_pmix_ext3x_component.events, &event->super);
1349             OBJ_RELEASE(event);
1350             break;
1351         }
1352     }
1353 
1354     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1355 
1356     op = OBJ_NEW(ext3x_opcaddy_t);
1357     op->opcbfunc = cbfunc;
1358     op->cbdata = cbdata;
1359 
1360     /* tell the library to deregister this handler */
1361     PMIx_Deregister_event_handler(evhandler, opcbfunc, op);
1362     return;
1363 }
1364 
1365 static void notify_complete(pmix_status_t status, void *cbdata)
1366 {
1367     ext3x_opcaddy_t *op = (ext3x_opcaddy_t*)cbdata;
1368     if (NULL != op->opcbfunc) {
1369         op->opcbfunc(ext3x_convert_rc(status), op->cbdata);
1370     }
1371     OBJ_RELEASE(op);
1372 }
1373 
1374 static int notify_event(int status,
1375                         const opal_process_name_t *source,
1376                         opal_pmix_data_range_t range,
1377                         opal_list_t *info,
1378                         opal_pmix_op_cbfunc_t cbfunc, void *cbdata)
1379 {
1380     ext3x_opcaddy_t *op;
1381     opal_value_t *kv;
1382     pmix_proc_t p, *pptr;
1383     pmix_status_t pstatus;
1384     size_t n;
1385     pmix_data_range_t prange;
1386     char *nsptr;
1387 
1388     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1389     if (0 >= opal_pmix_base.initialized) {
1390         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1391         return OPAL_ERR_NOT_INITIALIZED;
1392     }
1393 
1394     op = OBJ_NEW(ext3x_opcaddy_t);
1395     op->opcbfunc = cbfunc;
1396     op->cbdata = cbdata;
1397 
1398     /* convert the status */
1399     pstatus = ext3x_convert_opalrc(status);
1400 
1401     /* convert the source */
1402     if (NULL == source) {
1403         pptr = NULL;
1404     } else {
1405         if (NULL == (nsptr = ext3x_convert_jobid(source->jobid))) {
1406             OBJ_RELEASE(op);
1407             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1408             return OPAL_ERR_NOT_FOUND;
1409         }
1410         (void)opal_string_copy(p.nspace, nsptr, PMIX_MAX_NSLEN);
1411         p.rank = ext3x_convert_opalrank(source->vpid);
1412         pptr = &p;
1413     }
1414     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1415 
1416     /* convert the range */
1417     prange = ext3x_convert_opalrange(range);
1418 
1419     /* convert the list of info */
1420     if (NULL != info && 0 < (op->ninfo = opal_list_get_size(info))) {
1421         PMIX_INFO_CREATE(op->info, op->ninfo);
1422         n=0;
1423         OPAL_LIST_FOREACH(kv, info, opal_value_t) {
1424             (void)opal_string_copy(op->info[n].key, kv->key, PMIX_MAX_KEYLEN);
1425             /* little dicey here as we need to convert a status, if
1426              * provided, and it will be an int coming down to us */
1427             if (0 == strcmp(kv->key, OPAL_PMIX_JOB_TERM_STATUS)) {
1428                 op->info[n].value.type = PMIX_STATUS;
1429                 op->info[n].value.data.status = ext3x_convert_opalrc(kv->data.integer);
1430             } else {
1431                 ext3x_value_load(&op->info[n].value, kv);
1432             }
1433             ++n;
1434         }
1435     }
1436 
1437     /* ask the library to notify our clients */
1438     pstatus = PMIx_Notify_event(pstatus, pptr, prange, op->info, op->ninfo, notify_complete, op);
1439 
1440     return ext3x_convert_rc(pstatus);
1441 }
1442 
1443 static void relcbfunc(void *cbdata)
1444 {
1445     opal_list_t *results = (opal_list_t*)cbdata;
1446     if (NULL != results) {
1447         OPAL_LIST_RELEASE(results);
1448     }
1449 }
1450 
1451 static void infocbfunc(pmix_status_t status,
1452                        pmix_info_t *info, size_t ninfo,
1453                        void *cbdata,
1454                        pmix_release_cbfunc_t release_fn,
1455                        void *release_cbdata)
1456 {
1457     ext3x_opcaddy_t *cd = (ext3x_opcaddy_t*)cbdata;
1458     int rc = OPAL_SUCCESS;
1459     opal_list_t *results = NULL;
1460     opal_value_t *iptr;
1461     size_t n;
1462 
1463     OPAL_ACQUIRE_OBJECT(cd);
1464 
1465     /* convert the array of pmix_info_t to the list of info */
1466     if (NULL != info) {
1467         results = OBJ_NEW(opal_list_t);
1468         for (n=0; n < ninfo; n++) {
1469             iptr = OBJ_NEW(opal_value_t);
1470             opal_list_append(results, &iptr->super);
1471             iptr->key = strdup(info[n].key);
1472             if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
1473                 OPAL_ERROR_LOG(rc);
1474                 OPAL_LIST_RELEASE(results);
1475                 results = NULL;
1476                 break;
1477             }
1478         }
1479     }
1480 
1481     if (NULL != release_fn) {
1482         release_fn(release_cbdata);
1483     }
1484 
1485     /* return the values to the original requestor */
1486     if (NULL != cd->qcbfunc) {
1487         cd->qcbfunc(rc, results, cd->cbdata, relcbfunc, results);
1488     }
1489     OBJ_RELEASE(cd);
1490 }
1491 
1492 static void ext3x_query(opal_list_t *queries,
1493                          opal_pmix_info_cbfunc_t cbfunc, void *cbdata)
1494 {
1495     int rc;
1496     opal_value_t *ival;
1497     size_t n, nqueries, nq;
1498     ext3x_opcaddy_t *cd;
1499     pmix_status_t prc;
1500     opal_pmix_query_t *q;
1501 
1502     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1503     if (0 >= opal_pmix_base.initialized) {
1504         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1505         if (NULL != cbfunc) {
1506             cbfunc(OPAL_ERR_NOT_INITIALIZED, NULL, cbdata, NULL, NULL);
1507         }
1508         return;
1509     }
1510     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1511 
1512     /* create the caddy */
1513     cd = OBJ_NEW(ext3x_opcaddy_t);
1514 
1515     /* bozo check */
1516     if (NULL == queries || 0 == (nqueries = opal_list_get_size(queries))) {
1517         rc = OPAL_ERR_BAD_PARAM;
1518         goto CLEANUP;
1519     }
1520 
1521     /* setup the operation */
1522     cd->qcbfunc = cbfunc;
1523     cd->cbdata = cbdata;
1524     cd->nqueries = nqueries;
1525 
1526     /* convert the list to an array of query objects */
1527     PMIX_QUERY_CREATE(cd->queries, cd->nqueries);
1528     n=0;
1529     OPAL_LIST_FOREACH(q, queries, opal_pmix_query_t) {
1530         cd->queries[n].keys = opal_argv_copy(q->keys);
1531         cd->queries[n].nqual = opal_list_get_size(&q->qualifiers);
1532         if (0 < cd->queries[n].nqual) {
1533             PMIX_INFO_CREATE(cd->queries[n].qualifiers, cd->queries[n].nqual);
1534             nq = 0;
1535             OPAL_LIST_FOREACH(ival, &q->qualifiers, opal_value_t) {
1536                 (void)opal_string_copy(cd->queries[n].qualifiers[nq].key, ival->key, PMIX_MAX_KEYLEN);
1537                 ext3x_value_load(&cd->queries[n].qualifiers[nq].value, ival);
1538                 ++nq;
1539             }
1540         }
1541         ++n;
1542     }
1543 
1544     /* pass it down */
1545     if (PMIX_SUCCESS != (prc = PMIx_Query_info_nb(cd->queries, cd->nqueries,
1546                                                   infocbfunc, cd))) {
1547         /* do not hang! */
1548         rc = ext3x_convert_rc(prc);
1549         goto CLEANUP;
1550     }
1551 
1552     return;
1553 
1554   CLEANUP:
1555     if (NULL != cbfunc) {
1556         cbfunc(rc, NULL, cbdata, NULL, NULL);
1557     }
1558     OBJ_RELEASE(cd);
1559     return;
1560 }
1561 
1562 static void ext3x_log(opal_list_t *info,
1563                        opal_pmix_op_cbfunc_t cbfunc, void *cbdata)
1564 {
1565     int rc;
1566     opal_value_t *ival;
1567     size_t n, ninfo;
1568     ext3x_opcaddy_t *cd;
1569     pmix_status_t prc;
1570 
1571     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1572     if (0 >= opal_pmix_base.initialized) {
1573         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1574         if (NULL != cbfunc) {
1575             cbfunc(OPAL_ERR_NOT_INITIALIZED, cbdata);
1576         }
1577         return;
1578     }
1579     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1580 
1581     /* create the caddy */
1582     cd = OBJ_NEW(ext3x_opcaddy_t);
1583 
1584     /* bozo check */
1585     if (NULL == info || 0 == (ninfo = opal_list_get_size(info))) {
1586         rc = OPAL_ERR_BAD_PARAM;
1587         goto CLEANUP;
1588     }
1589 
1590     /* setup the operation */
1591     cd->opcbfunc = cbfunc;
1592     cd->cbdata = cbdata;
1593     cd->ninfo = ninfo;
1594 
1595     /* convert the list to an array of info objects */
1596     PMIX_INFO_CREATE(cd->info, cd->ninfo);
1597     n=0;
1598     OPAL_LIST_FOREACH(ival, info, opal_value_t) {
1599         (void)opal_string_copy(cd->info[n].key, ival->key, PMIX_MAX_KEYLEN);
1600         ext3x_value_load(&cd->info[n].value, ival);
1601         ++n;
1602     }
1603 
1604     /* pass it down */
1605     if (PMIX_SUCCESS != (prc = PMIx_Log_nb(cd->info, cd->ninfo, NULL, 0,
1606                                            opcbfunc, cd))) {
1607         /* do not hang! */
1608         rc = ext3x_convert_rc(prc);
1609         goto CLEANUP;
1610     }
1611 
1612     return;
1613 
1614   CLEANUP:
1615     if (NULL != cbfunc) {
1616         cbfunc(rc, cbdata);
1617     }
1618     OBJ_RELEASE(cd);
1619 }
1620 
1621 opal_pmix_alloc_directive_t ext3x_convert_allocdir(pmix_alloc_directive_t dir)
1622 {
1623     switch (dir) {
1624         case PMIX_ALLOC_NEW:
1625             return OPAL_PMIX_ALLOC_NEW;
1626         case PMIX_ALLOC_EXTEND:
1627             return OPAL_PMIX_ALLOC_EXTEND;
1628         case PMIX_ALLOC_RELEASE:
1629             return OPAL_PMIX_ALLOC_RELEASE;
1630         case PMIX_ALLOC_REAQUIRE:
1631             return OPAL_PMIX_ALLOC_REAQCUIRE;
1632         default:
1633             return OPAL_PMIX_ALLOC_UNDEF;
1634     }
1635 }
1636 
1637 int ext3x_convert_state(pmix_proc_state_t state)
1638 {
1639     switch(state) {
1640         case PMIX_PROC_STATE_UNDEF:
1641             return 0;
1642         case PMIX_PROC_STATE_PREPPED:
1643         case PMIX_PROC_STATE_LAUNCH_UNDERWAY:
1644             return 1;
1645         case PMIX_PROC_STATE_RESTART:
1646             return 2;
1647         case PMIX_PROC_STATE_TERMINATE:
1648             return 3;
1649         case PMIX_PROC_STATE_RUNNING:
1650             return 4;
1651         case PMIX_PROC_STATE_CONNECTED:
1652             return 5;
1653         case PMIX_PROC_STATE_UNTERMINATED:
1654             return 15;
1655         case PMIX_PROC_STATE_TERMINATED:
1656             return 20;
1657         case PMIX_PROC_STATE_KILLED_BY_CMD:
1658             return 51;
1659         case PMIX_PROC_STATE_ABORTED:
1660             return 52;
1661         case PMIX_PROC_STATE_FAILED_TO_START:
1662             return 53;
1663         case PMIX_PROC_STATE_ABORTED_BY_SIG:
1664             return 54;
1665         case PMIX_PROC_STATE_TERM_WO_SYNC:
1666             return 55;
1667         case PMIX_PROC_STATE_COMM_FAILED:
1668             return 56;
1669         case PMIX_PROC_STATE_CALLED_ABORT:
1670             return 58;
1671         case PMIX_PROC_STATE_MIGRATING:
1672             return 60;
1673         case PMIX_PROC_STATE_CANNOT_RESTART:
1674             return 61;
1675         case PMIX_PROC_STATE_TERM_NON_ZERO:
1676             return 62;
1677         case PMIX_PROC_STATE_FAILED_TO_LAUNCH:
1678             return 63;
1679         default:
1680             return 0;  // undef
1681     }
1682 }
1683 
1684 pmix_proc_state_t ext3x_convert_opalstate(int state)
1685 {
1686     switch(state) {
1687         case 0:
1688             return PMIX_PROC_STATE_UNDEF;
1689         case 1:
1690             return PMIX_PROC_STATE_LAUNCH_UNDERWAY;
1691         case 2:
1692             return PMIX_PROC_STATE_RESTART;
1693         case 3:
1694             return PMIX_PROC_STATE_TERMINATE;
1695         case 4:
1696             return PMIX_PROC_STATE_RUNNING;
1697         case 5:
1698             return PMIX_PROC_STATE_CONNECTED;
1699         case 51:
1700             return PMIX_PROC_STATE_KILLED_BY_CMD;
1701         case 52:
1702             return PMIX_PROC_STATE_ABORTED;
1703         case 53:
1704             return PMIX_PROC_STATE_FAILED_TO_START;
1705         case 54:
1706             return PMIX_PROC_STATE_ABORTED_BY_SIG;
1707         case 55:
1708             return PMIX_PROC_STATE_TERM_WO_SYNC;
1709         case 56:
1710             return PMIX_PROC_STATE_COMM_FAILED;
1711         case 58:
1712             return PMIX_PROC_STATE_CALLED_ABORT;
1713         case 59:
1714             return PMIX_PROC_STATE_MIGRATING;
1715         case 61:
1716             return PMIX_PROC_STATE_CANNOT_RESTART;
1717         case 62:
1718             return PMIX_PROC_STATE_TERM_NON_ZERO;
1719         case 63:
1720             return PMIX_PROC_STATE_FAILED_TO_LAUNCH;
1721         default:
1722             return PMIX_PROC_STATE_UNDEF;
1723     }
1724 }
1725 
1726 /****  INSTANTIATE INTERNAL CLASSES  ****/
1727 OBJ_CLASS_INSTANCE(opal_ext3x_jobid_trkr_t,
1728                    opal_list_item_t,
1729                    NULL, NULL);
1730 
1731 static void evcon(opal_ext3x_event_t *p)
1732 {
1733     OPAL_PMIX_CONSTRUCT_LOCK(&p->lock);
1734     p->handler = NULL;
1735     p->cbdata = NULL;
1736 }
1737 static void evdes(opal_ext3x_event_t *p)
1738 {
1739     OPAL_PMIX_DESTRUCT_LOCK(&p->lock);
1740 }
1741 OBJ_CLASS_INSTANCE(opal_ext3x_event_t,
1742                    opal_list_item_t,
1743                    evcon, evdes);
1744 
1745 static void opcon(ext3x_opcaddy_t *p)
1746 {
1747     memset(&p->p, 0, sizeof(pmix_proc_t));
1748     p->nspace = NULL;
1749     p->procs = NULL;
1750     p->nprocs = 0;
1751     p->pdata = NULL;
1752     p->npdata = 0;
1753     p->error_procs = NULL;
1754     p->nerror_procs = 0;
1755     p->info = NULL;
1756     p->ninfo = 0;
1757     p->apps = NULL;
1758     p->sz = 0;
1759     OPAL_PMIX_CONSTRUCT_LOCK(&p->lock);
1760     p->codes = NULL;
1761     p->pcodes = NULL;
1762     p->ncodes = 0;
1763     p->queries = NULL;
1764     p->nqueries = 0;
1765     p->event = NULL;
1766     p->opcbfunc = NULL;
1767     p->mdxcbfunc = NULL;
1768     p->valcbfunc = NULL;
1769     p->lkcbfunc = NULL;
1770     p->spcbfunc = NULL;
1771     p->evregcbfunc = NULL;
1772     p->qcbfunc = NULL;
1773     p->cbdata = NULL;
1774 }
1775 static void opdes(ext3x_opcaddy_t *p)
1776 {
1777     OPAL_PMIX_DESTRUCT_LOCK(&p->lock);
1778     if (NULL != p->nspace) {
1779         free(p->nspace);
1780     }
1781     if (NULL != p->procs) {
1782         PMIX_PROC_FREE(p->procs, p->nprocs);
1783     }
1784     if (NULL != p->pdata) {
1785         PMIX_PDATA_FREE(p->pdata, p->npdata);
1786     }
1787     if (NULL != p->error_procs) {
1788         PMIX_PROC_FREE(p->error_procs, p->nerror_procs);
1789     }
1790     if (NULL != p->info) {
1791         PMIX_INFO_FREE(p->info, p->ninfo);
1792     }
1793     if (NULL != p->apps) {
1794         PMIX_APP_FREE(p->apps, p->sz);
1795     }
1796     if (NULL != p->pcodes) {
1797         free(p->pcodes);
1798     }
1799     if (NULL != p->queries) {
1800         PMIX_QUERY_FREE(p->queries, p->nqueries);
1801     }
1802 }
1803 OBJ_CLASS_INSTANCE(ext3x_opcaddy_t,
1804                    opal_object_t,
1805                    opcon, opdes);
1806 
1807 static void ocadcon(ext3x_opalcaddy_t *p)
1808 {
1809     OBJ_CONSTRUCT(&p->procs, opal_list_t);
1810     OBJ_CONSTRUCT(&p->info, opal_list_t);
1811     OBJ_CONSTRUCT(&p->apps, opal_list_t);
1812     p->opcbfunc = NULL;
1813     p->dmdxfunc = NULL;
1814     p->mdxcbfunc = NULL;
1815     p->lkupcbfunc = NULL;
1816     p->spwncbfunc = NULL;
1817     p->cbdata = NULL;
1818     p->odmdxfunc = NULL;
1819     p->infocbfunc = NULL;
1820     p->toolcbfunc = NULL;
1821     p->ocbdata = NULL;
1822 }
1823 static void ocaddes(ext3x_opalcaddy_t *p)
1824 {
1825     OPAL_LIST_DESTRUCT(&p->procs);
1826     OPAL_LIST_DESTRUCT(&p->info);
1827     OPAL_LIST_DESTRUCT(&p->apps);
1828 }
1829 OBJ_CLASS_INSTANCE(ext3x_opalcaddy_t,
1830                    opal_object_t,
1831                    ocadcon, ocaddes);
1832 
1833 static void tscon(ext3x_threadshift_t *p)
1834 {
1835     OPAL_PMIX_CONSTRUCT_LOCK(&p->lock);
1836     p->msg = NULL;
1837     p->strings = NULL;
1838     p->source = NULL;
1839     p->event_codes = NULL;
1840     p->info = NULL;
1841     OBJ_CONSTRUCT(&p->results, opal_list_t);
1842     p->evhandler = NULL;
1843     p->nondefault = false;
1844     p->cbfunc = NULL;
1845     p->opcbfunc = NULL;
1846     p->cbdata = NULL;
1847 }
1848 static void tsdes(ext3x_threadshift_t *p)
1849 {
1850     OPAL_PMIX_DESTRUCT_LOCK(&p->lock);
1851     if (NULL != p->strings) {
1852         free(p->strings);
1853     }
1854     OPAL_LIST_DESTRUCT(&p->results);
1855 }
1856 OBJ_CLASS_INSTANCE(ext3x_threadshift_t,
1857                    opal_object_t,
1858                    tscon, tsdes);
1859 
1860 static void dmcon(opal_ext3x_dmx_trkr_t *p)
1861 {
1862     p->nspace = NULL;
1863     p->cbfunc = NULL;
1864     p->cbdata = NULL;
1865 }
1866 static void dmdes(opal_ext3x_dmx_trkr_t *p)
1867 {
1868     if (NULL != p->nspace) {
1869         free(p->nspace);
1870     }
1871 }
1872 OBJ_CLASS_INSTANCE(opal_ext3x_dmx_trkr_t,
1873                    opal_list_item_t,
1874                    dmcon, dmdes);

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