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

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

DEFINITIONS

This source file includes following definitions.
  1. opal_opcbfunc
  2. server_client_connected_fn
  3. server_client_finalized_fn
  4. server_abort_fn
  5. _data_release
  6. opmdx_response
  7. server_fencenb_fn
  8. server_dmodex_req_fn
  9. server_publish_fn
  10. opal_lkupcbfunc
  11. server_lookup_fn
  12. server_unpublish_fn
  13. opal_spncbfunc
  14. server_spawn_fn
  15. server_connect_fn
  16. server_disconnect_fn
  17. server_register_events
  18. server_deregister_events
  19. server_notify_event
  20. _info_rel
  21. info_cbfunc
  22. server_query
  23. toolcbfunc
  24. server_tool_connection
  25. server_log
  26. server_allocate
  27. server_job_control
  28. server_iof_pull
  29. server_stdin

   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-2017 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$
  10  *
  11  * Additional copyrights may follow
  12  *
  13  * $HEADER$
  14  */
  15 
  16 #include "opal_config.h"
  17 #include "opal/constants.h"
  18 #include "opal/types.h"
  19 
  20 #ifdef HAVE_STRING_H
  21 #include <string.h>
  22 #endif
  23 #ifdef HAVE_UNISTD_H
  24 #include <unistd.h>
  25 #endif
  26 
  27 #include "opal/dss/dss.h"
  28 #include "opal/mca/event/event.h"
  29 #include "opal/mca/hwloc/base/base.h"
  30 #include "opal/runtime/opal.h"
  31 #include "opal/runtime/opal_progress_threads.h"
  32 #include "opal/threads/threads.h"
  33 #include "opal/util/argv.h"
  34 #include "opal/util/error.h"
  35 #include "opal/util/output.h"
  36 #include "opal/util/proc.h"
  37 #include "opal/util/show_help.h"
  38 #include "opal/util/string_copy.h"
  39 #include "opal/mca/pmix/base/base.h"
  40 #include "ext3x.h"
  41 
  42 #include "pmix.h"
  43 #include "pmix_server.h"
  44 
  45 /****    N.O.R.T.H.B.O.U.N.D   I.N.T.E.R.F.A.C.E.S     ****/
  46 
  47 /* These are the interfaces used by the embedded PMIx server
  48  * to call up into ORTE for service requests */
  49 
  50 static pmix_status_t server_client_connected_fn(const pmix_proc_t *proc, void* server_object,
  51                                                 pmix_op_cbfunc_t cbfunc, void *cbdata);
  52 static pmix_status_t server_client_finalized_fn(const pmix_proc_t *proc, void* server_object,
  53                                                 pmix_op_cbfunc_t cbfunc, void *cbdata);
  54 static pmix_status_t server_abort_fn(const pmix_proc_t *proc, void *server_object,
  55                                      int status, const char msg[],
  56                                      pmix_proc_t procs[], size_t nprocs,
  57                                      pmix_op_cbfunc_t cbfunc, void *cbdata);
  58 static pmix_status_t server_fencenb_fn(const pmix_proc_t procs[], size_t nprocs,
  59                                        const pmix_info_t info[], size_t ninfo,
  60                                        char *data, size_t ndata,
  61                                        pmix_modex_cbfunc_t cbfunc, void *cbdata);
  62 static pmix_status_t server_dmodex_req_fn(const pmix_proc_t *proc,
  63                                           const pmix_info_t info[], size_t ninfo,
  64                                           pmix_modex_cbfunc_t cbfunc, void *cbdata);
  65 static pmix_status_t server_publish_fn(const pmix_proc_t *proc,
  66                                        const pmix_info_t info[], size_t ninfo,
  67                                        pmix_op_cbfunc_t cbfunc, void *cbdata);
  68 static pmix_status_t server_lookup_fn(const pmix_proc_t *proc,  char **keys,
  69                                       const pmix_info_t info[], size_t ninfo,
  70                                       pmix_lookup_cbfunc_t cbfunc, void *cbdata);
  71 static pmix_status_t server_unpublish_fn(const pmix_proc_t *proc, char **keys,
  72                                          const pmix_info_t info[], size_t ninfo,
  73                                          pmix_op_cbfunc_t cbfunc, void *cbdata);
  74 static pmix_status_t server_spawn_fn(const pmix_proc_t *proc,
  75                                      const pmix_info_t job_info[], size_t ninfo,
  76                                      const pmix_app_t apps[], size_t napps,
  77                                      pmix_spawn_cbfunc_t cbfunc, void *cbdata);
  78 static pmix_status_t server_connect_fn(const pmix_proc_t procs[], size_t nprocs,
  79                                        const pmix_info_t info[], size_t ninfo,
  80                                        pmix_op_cbfunc_t cbfunc, void *cbdata);
  81 static pmix_status_t server_disconnect_fn(const pmix_proc_t procs[], size_t nprocs,
  82                                           const pmix_info_t info[], size_t ninfo,
  83                                           pmix_op_cbfunc_t cbfunc, void *cbdata);
  84 static pmix_status_t server_register_events(pmix_status_t *codes, size_t ncodes,
  85                                             const pmix_info_t info[], size_t ninfo,
  86                                             pmix_op_cbfunc_t cbfunc, void *cbdata);
  87 static pmix_status_t server_deregister_events(pmix_status_t *codes, size_t ncodes,
  88                                               pmix_op_cbfunc_t cbfunc, void *cbdata);
  89 static pmix_status_t server_notify_event(pmix_status_t code,
  90                                          const pmix_proc_t *source,
  91                                          pmix_data_range_t range,
  92                                          pmix_info_t info[], size_t ninfo,
  93                                          pmix_op_cbfunc_t cbfunc, void *cbdata);
  94 static pmix_status_t server_query(pmix_proc_t *proct,
  95                                   pmix_query_t *queryies, size_t nqueries,
  96                                   pmix_info_cbfunc_t cbfunc,
  97                                   void *cbdata);
  98 static void server_tool_connection(pmix_info_t *info, size_t ninfo,
  99                                    pmix_tool_connection_cbfunc_t cbfunc,
 100                                    void *cbdata);
 101 static void server_log(const pmix_proc_t *client,
 102                        const pmix_info_t data[], size_t ndata,
 103                        const pmix_info_t directives[], size_t ndirs,
 104                        pmix_op_cbfunc_t cbfunc, void *cbdata);
 105 
 106 static pmix_status_t server_allocate(const pmix_proc_t *client,
 107                                      pmix_alloc_directive_t directive,
 108                                      const pmix_info_t data[], size_t ndata,
 109                                      pmix_info_cbfunc_t cbfunc, void *cbdata);
 110 
 111 static pmix_status_t server_job_control(const pmix_proc_t *requestor,
 112                                         const pmix_proc_t targets[], size_t ntargets,
 113                                         const pmix_info_t directives[], size_t ndirs,
 114                                         pmix_info_cbfunc_t cbfunc, void *cbdata);
 115 static pmix_status_t server_iof_pull(const pmix_proc_t procs[], size_t nprocs,
 116                                      const pmix_info_t directives[], size_t ndirs,
 117                                      pmix_iof_channel_t channels,
 118                                      pmix_op_cbfunc_t cbfunc, void *cbdata);
 119 static pmix_status_t server_stdin(const pmix_proc_t *source,
 120                                   const pmix_proc_t targets[], size_t ntargets,
 121                                   const pmix_info_t directives[], size_t ndirs,
 122                                   const pmix_byte_object_t *bo,
 123                                   pmix_op_cbfunc_t cbfunc, void *cbdata);
 124 
 125 pmix_server_module_t mymodule = {
 126     .client_connected = server_client_connected_fn,
 127     .client_finalized = server_client_finalized_fn,
 128     .abort = server_abort_fn,
 129     .fence_nb = server_fencenb_fn,
 130     .direct_modex = server_dmodex_req_fn,
 131     .publish = server_publish_fn,
 132     .lookup = server_lookup_fn,
 133     .unpublish = server_unpublish_fn,
 134     .spawn = server_spawn_fn,
 135     .connect = server_connect_fn,
 136     .disconnect = server_disconnect_fn,
 137     .register_events = server_register_events,
 138     .deregister_events = server_deregister_events,
 139     .notify_event = server_notify_event,
 140     .query = server_query,
 141     .tool_connected = server_tool_connection,
 142     .log = server_log,
 143     .allocate = server_allocate,
 144     .job_control = server_job_control,
 145     /* we do not support monitoring, but use the
 146      * PMIx internal monitoring capability */
 147     .iof_pull = server_iof_pull,
 148     .push_stdin = server_stdin
 149 };
 150 
 151 opal_pmix_server_module_t *host_module = NULL;
 152 
 153 
 154 static void opal_opcbfunc(int status, void *cbdata)
 155 {
 156     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 157 
 158     OPAL_ACQUIRE_OBJECT(opalcaddy);
 159     if (NULL != opalcaddy->opcbfunc) {
 160         opalcaddy->opcbfunc(ext3x_convert_opalrc(status), opalcaddy->cbdata);
 161     }
 162     OBJ_RELEASE(opalcaddy);
 163 }
 164 
 165 static pmix_status_t server_client_connected_fn(const pmix_proc_t *p, void *server_object,
 166                                                 pmix_op_cbfunc_t cbfunc, void *cbdata)
 167 {
 168     int rc;
 169     opal_process_name_t proc;
 170     ext3x_opalcaddy_t *opalcaddy;
 171 
 172     if (NULL == host_module || NULL == host_module->client_connected) {
 173         return PMIX_SUCCESS;
 174     }
 175 
 176     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 177     opalcaddy->opcbfunc = cbfunc;
 178     opalcaddy->cbdata = cbdata;
 179 
 180     /* convert the nspace/rank to an opal_process_name_t */
 181     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 182         return ext3x_convert_opalrc(rc);
 183     }
 184     proc.vpid = ext3x_convert_rank(p->rank);
 185 
 186     /* pass it up */
 187     rc = host_module->client_connected(&proc, server_object,
 188                                        opal_opcbfunc, opalcaddy);
 189     return ext3x_convert_opalrc(rc);
 190 }
 191 
 192 static pmix_status_t server_client_finalized_fn(const pmix_proc_t *p, void* server_object,
 193                                                 pmix_op_cbfunc_t cbfunc, void *cbdata)
 194 {
 195     int rc;
 196     ext3x_opalcaddy_t *opalcaddy;
 197     opal_process_name_t proc;
 198 
 199     if (NULL == host_module || NULL == host_module->client_finalized) {
 200         return PMIX_SUCCESS;
 201     }
 202 
 203     /* convert the nspace/rank to an opal_process_name_t */
 204     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 205         return ext3x_convert_opalrc(rc);
 206     }
 207     proc.vpid = ext3x_convert_rank(p->rank);
 208 
 209     /* setup the caddy */
 210     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 211     opalcaddy->opcbfunc = cbfunc;
 212     opalcaddy->cbdata = cbdata;
 213 
 214     /* pass it up */
 215     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 216                         "%s CLIENT %s FINALIZED",
 217                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 218                         OPAL_NAME_PRINT(proc));
 219     rc = host_module->client_finalized(&proc, server_object, opal_opcbfunc, opalcaddy);
 220     if (OPAL_SUCCESS != rc) {
 221         OBJ_RELEASE(opalcaddy);
 222     }
 223     return ext3x_convert_opalrc(rc);
 224 }
 225 
 226 static pmix_status_t server_abort_fn(const pmix_proc_t *p, void *server_object,
 227                                      int status, const char msg[],
 228                                      pmix_proc_t procs[], size_t nprocs,
 229                                      pmix_op_cbfunc_t cbfunc, void *cbdata)
 230 {
 231     size_t n;
 232     opal_namelist_t *nm;
 233     opal_process_name_t proc;
 234     int rc;
 235     ext3x_opalcaddy_t *opalcaddy;
 236 
 237     if (NULL == host_module || NULL == host_module->abort) {
 238         return PMIX_ERR_NOT_SUPPORTED;
 239     }
 240 
 241     /* convert the nspace/rank to an opal_process_name_t */
 242     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 243         return ext3x_convert_opalrc(rc);
 244     }
 245     proc.vpid = ext3x_convert_rank(p->rank);
 246 
 247     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 248                         "%s CLIENT %s CALLED ABORT",
 249                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 250                         OPAL_NAME_PRINT(proc));
 251 
 252     /* setup the caddy */
 253     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 254     opalcaddy->opcbfunc = cbfunc;
 255     opalcaddy->cbdata = cbdata;
 256 
 257     /* convert the array of pmix_proc_t to the list of procs */
 258     for (n=0; n < nprocs; n++) {
 259         nm = OBJ_NEW(opal_namelist_t);
 260         opal_list_append(&opalcaddy->procs, &nm->super);
 261         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) {
 262             OBJ_RELEASE(opalcaddy);
 263             return ext3x_convert_opalrc(rc);
 264         }
 265         nm->name.vpid = ext3x_convert_rank(procs[n].rank);
 266     }
 267 
 268     /* pass it up */
 269     rc = host_module->abort(&proc, server_object, status, msg,
 270                             &opalcaddy->procs, opal_opcbfunc, opalcaddy);
 271     if (OPAL_SUCCESS != rc) {
 272         OBJ_RELEASE(opalcaddy);
 273     }
 274     return ext3x_convert_opalrc(rc);
 275 }
 276 
 277 static void _data_release(void *cbdata)
 278 {
 279     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 280 
 281     if (NULL != opalcaddy->odmdxfunc) {
 282         opalcaddy->odmdxfunc(opalcaddy->ocbdata);
 283     }
 284     OBJ_RELEASE(opalcaddy);
 285 }
 286 
 287 static void opmdx_response(int status, const char *data, size_t sz, void *cbdata,
 288                            opal_pmix_release_cbfunc_t relcbfunc, void *relcbdata)
 289 {
 290     pmix_status_t rc;
 291     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 292     opal_ext3x_dmx_trkr_t *dmdx;
 293 
 294     rc = ext3x_convert_rc(status);
 295     if (NULL != opalcaddy->mdxcbfunc) {
 296         opalcaddy->odmdxfunc = relcbfunc;
 297         opalcaddy->ocbdata = relcbdata;
 298         opalcaddy->mdxcbfunc(rc, data, sz, opalcaddy->cbdata,
 299                              _data_release, opalcaddy);
 300     } else {
 301         OBJ_RELEASE(opalcaddy);
 302     }
 303     if (opal_pmix_collect_all_data) {
 304         /* if we were collecting all data, then check for any pending
 305          * dmodx requests that we cached and notify them that the
 306          * data has arrived */
 307         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 308         while (NULL != (dmdx = (opal_ext3x_dmx_trkr_t*)opal_list_remove_first(&mca_pmix_ext3x_component.dmdx))) {
 309             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 310             dmdx->cbfunc(PMIX_SUCCESS, NULL, 0, dmdx->cbdata, NULL, NULL);
 311             OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 312             OBJ_RELEASE(dmdx);
 313         }
 314         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 315     }
 316 }
 317 
 318 static pmix_status_t server_fencenb_fn(const pmix_proc_t procs[], size_t nprocs,
 319                                        const pmix_info_t info[], size_t ninfo,
 320                                        char *data, size_t ndata,
 321                                        pmix_modex_cbfunc_t cbfunc, void *cbdata)
 322 {
 323     ext3x_opalcaddy_t *opalcaddy;
 324     size_t n;
 325     opal_namelist_t *nm;
 326     opal_value_t *iptr;
 327     int rc;
 328 
 329     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 330                         "%s FENCE CALLED", OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
 331 
 332     if (NULL == host_module || NULL == host_module->fence_nb) {
 333         return PMIX_ERR_NOT_SUPPORTED;
 334     }
 335     /* setup the caddy */
 336     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 337     opalcaddy->mdxcbfunc = cbfunc;
 338     opalcaddy->cbdata = cbdata;
 339 
 340     /* convert the array of pmix_proc_t to the list of procs */
 341     for (n=0; n < nprocs; n++) {
 342         nm = OBJ_NEW(opal_namelist_t);
 343         opal_list_append(&opalcaddy->procs, &nm->super);
 344         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) {
 345             OBJ_RELEASE(opalcaddy);
 346             return ext3x_convert_opalrc(rc);
 347         }
 348         nm->name.vpid = ext3x_convert_rank(procs[n].rank);
 349     }
 350 
 351     /* convert the array of pmix_info_t to the list of info */
 352     for (n=0; n < ninfo; n++) {
 353         iptr = OBJ_NEW(opal_value_t);
 354         opal_list_append(&opalcaddy->info, &iptr->super);
 355         iptr->key = strdup(info[n].key);
 356         if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
 357             OBJ_RELEASE(opalcaddy);
 358             return ext3x_convert_opalrc(rc);
 359         }
 360     }
 361 
 362     /* pass it up */
 363     rc = host_module->fence_nb(&opalcaddy->procs, &opalcaddy->info,
 364                                data, ndata, opmdx_response, opalcaddy);
 365     if (OPAL_SUCCESS != rc) {
 366         OBJ_RELEASE(opalcaddy);
 367     }
 368     return ext3x_convert_opalrc(rc);
 369 }
 370 
 371 static pmix_status_t server_dmodex_req_fn(const pmix_proc_t *p,
 372                                           const pmix_info_t info[], size_t ninfo,
 373                                           pmix_modex_cbfunc_t cbfunc, void *cbdata)
 374 {
 375     int rc;
 376     ext3x_opalcaddy_t *opalcaddy;
 377     opal_process_name_t proc;
 378     opal_value_t *iptr;
 379     size_t n;
 380     opal_ext3x_dmx_trkr_t *dmdx;
 381 
 382     if (NULL == host_module || NULL == host_module->direct_modex) {
 383         return PMIX_ERR_NOT_SUPPORTED;
 384     }
 385 
 386     /* convert the nspace/rank to an opal_process_name_t */
 387     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 388         return ext3x_convert_opalrc(rc);
 389     }
 390     proc.vpid = ext3x_convert_rank(p->rank);
 391 
 392     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 393                         "%s CLIENT %s CALLED DMODX",
 394                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 395                         OPAL_NAME_PRINT(proc));
 396 
 397     /* setup the caddy */
 398     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 399     opalcaddy->mdxcbfunc = cbfunc;
 400     opalcaddy->cbdata = cbdata;
 401 
 402     /* this function should only get called if we are in an async modex.
 403      * If we are also collecting data, then the fence_nb will eventually
 404      * complete and return all the required data down to the pmix
 405      * server beneath us. Thus, we only need to track the dmodex_req
 406      * and ensure that the release gets called once the data has
 407      * arrived - this will trigger the pmix server to tell the
 408      * client that the data is available */
 409     if (opal_pmix_base_async_modex && opal_pmix_collect_all_data) {
 410         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 411         dmdx = OBJ_NEW(opal_ext3x_dmx_trkr_t);
 412         dmdx->cbfunc = cbfunc;
 413         dmdx->cbdata = cbdata;
 414         opal_list_append(&mca_pmix_ext3x_component.dmdx, &dmdx->super);
 415         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 416         return PMIX_SUCCESS;
 417     }
 418 
 419     /* convert the array of pmix_info_t to the list of info */
 420     for (n=0; n < ninfo; n++) {
 421         iptr = OBJ_NEW(opal_value_t);
 422         opal_list_append(&opalcaddy->info, &iptr->super);
 423         iptr->key = strdup(info[n].key);
 424         if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
 425             OBJ_RELEASE(opalcaddy);
 426             return ext3x_convert_opalrc(rc);
 427         }
 428     }
 429 
 430     /* pass it up */
 431     rc = host_module->direct_modex(&proc, &opalcaddy->info, opmdx_response, opalcaddy);
 432     if (OPAL_SUCCESS != rc && OPAL_ERR_IN_PROCESS != rc) {
 433         OBJ_RELEASE(opalcaddy);
 434     }
 435     if (OPAL_ERR_IN_PROCESS == rc) {
 436         rc = OPAL_SUCCESS;
 437     }
 438     return ext3x_convert_opalrc(rc);
 439 }
 440 
 441 static pmix_status_t server_publish_fn(const pmix_proc_t *p,
 442                                        const pmix_info_t info[], size_t ninfo,
 443                                        pmix_op_cbfunc_t cbfunc, void *cbdata)
 444 {
 445     int rc;
 446     size_t n;
 447     ext3x_opalcaddy_t *opalcaddy;
 448     opal_process_name_t proc;
 449     opal_value_t *oinfo;
 450 
 451     if (NULL == host_module || NULL == host_module->publish) {
 452         return PMIX_ERR_NOT_SUPPORTED;
 453     }
 454 
 455    /* convert the nspace/rank to an opal_process_name_t */
 456     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 457         return ext3x_convert_opalrc(rc);
 458     }
 459     proc.vpid = ext3x_convert_rank(p->rank);
 460 
 461     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 462                         "%s CLIENT %s CALLED PUBLISH",
 463                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 464                         OPAL_NAME_PRINT(proc));
 465 
 466     /* setup the caddy */
 467     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 468     opalcaddy->opcbfunc = cbfunc;
 469     opalcaddy->cbdata = cbdata;
 470 
 471     /* convert the info array */
 472     for (n=0; n < ninfo; n++) {
 473         oinfo = OBJ_NEW(opal_value_t);
 474         opal_list_append(&opalcaddy->info, &oinfo->super);
 475         oinfo->key = strdup(info[n].key);
 476         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
 477             OBJ_RELEASE(opalcaddy);
 478             return ext3x_convert_opalrc(rc);
 479         }
 480     }
 481 
 482     /* pass it up */
 483     rc = host_module->publish(&proc, &opalcaddy->info, opal_opcbfunc, opalcaddy);
 484     if (OPAL_SUCCESS != rc) {
 485         OBJ_RELEASE(opalcaddy);
 486     }
 487 
 488     return ext3x_convert_opalrc(rc);
 489 }
 490 
 491 static void opal_lkupcbfunc(int status,
 492                             opal_list_t *data,
 493                             void *cbdata)
 494 {
 495     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 496     pmix_status_t rc;
 497     pmix_pdata_t *d=NULL;
 498     size_t nd=0, n;
 499     opal_pmix_pdata_t *p;
 500 
 501     if (NULL != opalcaddy->lkupcbfunc) {
 502         rc = ext3x_convert_opalrc(status);
 503         /* convert any returned data */
 504         if (NULL != data) {
 505             nd = opal_list_get_size(data);
 506             PMIX_PDATA_CREATE(d, nd);
 507             n=0;
 508             OPAL_LIST_FOREACH(p, data, opal_pmix_pdata_t) {
 509                 /* convert the jobid */
 510                 (void)opal_snprintf_jobid(d[n].proc.nspace, PMIX_MAX_NSLEN, p->proc.jobid);
 511                 d[n].proc.rank = ext3x_convert_opalrank(p->proc.vpid);
 512                 (void)opal_string_copy(d[n].key, p->value.key, PMIX_MAX_KEYLEN);
 513                 ext3x_value_load(&d[n].value, &p->value);
 514             }
 515         }
 516         opalcaddy->lkupcbfunc(rc, d, nd, opalcaddy->cbdata);
 517         PMIX_PDATA_FREE(d, nd);
 518     }
 519     OBJ_RELEASE(opalcaddy);
 520 }
 521 
 522 static pmix_status_t server_lookup_fn(const pmix_proc_t *p, char **keys,
 523                                       const pmix_info_t info[], size_t ninfo,
 524                                       pmix_lookup_cbfunc_t cbfunc, void *cbdata)
 525 {
 526     int rc;
 527     ext3x_opalcaddy_t *opalcaddy;
 528     opal_process_name_t proc;
 529     opal_value_t *iptr;
 530     size_t n;
 531 
 532     if (NULL == host_module || NULL == host_module->lookup) {
 533         return PMIX_ERR_NOT_SUPPORTED;
 534     }
 535 
 536     /* convert the nspace/rank to an opal_process_name_t */
 537     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 538         return ext3x_convert_opalrc(rc);
 539     }
 540     proc.vpid = ext3x_convert_rank(p->rank);
 541 
 542     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 543                         "%s CLIENT %s CALLED LOOKUP",
 544                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 545                         OPAL_NAME_PRINT(proc));
 546 
 547     /* setup the caddy */
 548     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 549     opalcaddy->lkupcbfunc = cbfunc;
 550     opalcaddy->cbdata = cbdata;
 551 
 552     /* convert the array of pmix_info_t to the list of info */
 553     for (n=0; n < ninfo; n++) {
 554         iptr = OBJ_NEW(opal_value_t);
 555         opal_list_append(&opalcaddy->info, &iptr->super);
 556         iptr->key = strdup(info[n].key);
 557         if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
 558             OBJ_RELEASE(opalcaddy);
 559             return ext3x_convert_opalrc(rc);
 560         }
 561     }
 562 
 563     /* pass it up */
 564     rc = host_module->lookup(&proc, keys, &opalcaddy->info, opal_lkupcbfunc, opalcaddy);
 565     if (OPAL_SUCCESS != rc) {
 566         OBJ_RELEASE(opalcaddy);
 567     }
 568 
 569     return ext3x_convert_opalrc(rc);
 570 }
 571 
 572 
 573 static pmix_status_t server_unpublish_fn(const pmix_proc_t *p, char **keys,
 574                                          const pmix_info_t info[], size_t ninfo,
 575                                          pmix_op_cbfunc_t cbfunc, void *cbdata)
 576 {
 577     int rc;
 578     ext3x_opalcaddy_t *opalcaddy;
 579     opal_process_name_t proc;
 580     opal_value_t *iptr;
 581     size_t n;
 582 
 583     if (NULL == host_module || NULL == host_module->unpublish) {
 584         return PMIX_SUCCESS;
 585     }
 586 
 587     /* convert the nspace/rank to an opal_process_name_t */
 588     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 589         return ext3x_convert_opalrc(rc);
 590     }
 591     proc.vpid = ext3x_convert_rank(p->rank);
 592 
 593     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 594                         "%s CLIENT %s CALLED UNPUBLISH",
 595                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 596                         OPAL_NAME_PRINT(proc));
 597 
 598     /* setup the caddy */
 599     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 600     opalcaddy->opcbfunc = cbfunc;
 601     opalcaddy->cbdata = cbdata;
 602 
 603     /* convert the array of pmix_info_t to the list of info */
 604     for (n=0; n < ninfo; n++) {
 605         iptr = OBJ_NEW(opal_value_t);
 606         opal_list_append(&opalcaddy->info, &iptr->super);
 607         iptr->key = strdup(info[n].key);
 608         if (OPAL_SUCCESS != (rc = ext3x_value_unload(iptr, &info[n].value))) {
 609             OBJ_RELEASE(opalcaddy);
 610             return ext3x_convert_opalrc(rc);
 611         }
 612     }
 613 
 614     /* pass it up */
 615     rc = host_module->unpublish(&proc, keys, &opalcaddy->info, opal_opcbfunc, opalcaddy);
 616     if (OPAL_SUCCESS != rc) {
 617         OBJ_RELEASE(opalcaddy);
 618     }
 619 
 620     return ext3x_convert_opalrc(rc);
 621 }
 622 
 623 static void opal_spncbfunc(int status, opal_jobid_t jobid, void *cbdata)
 624 {
 625     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 626     pmix_status_t rc;
 627     char nspace[PMIX_MAX_NSLEN];
 628 
 629     if (NULL != opalcaddy->spwncbfunc) {
 630         rc = ext3x_convert_opalrc(status);
 631         /* convert the jobid */
 632         (void)opal_snprintf_jobid(nspace, PMIX_MAX_NSLEN, jobid);
 633         opalcaddy->spwncbfunc(rc, nspace, opalcaddy->cbdata);
 634     }
 635     OBJ_RELEASE(opalcaddy);
 636 }
 637 
 638 static pmix_status_t server_spawn_fn(const pmix_proc_t *p,
 639                                      const pmix_info_t job_info[], size_t ninfo,
 640                                      const pmix_app_t apps[], size_t napps,
 641                                      pmix_spawn_cbfunc_t cbfunc, void *cbdata)
 642 {
 643     ext3x_opalcaddy_t *opalcaddy;
 644     opal_process_name_t proc;
 645     opal_pmix_app_t *app;
 646     opal_value_t *oinfo;
 647     size_t k, n;
 648     int rc;
 649 
 650     if (NULL == host_module || NULL == host_module->spawn) {
 651         return PMIX_ERR_NOT_SUPPORTED;
 652     }
 653 
 654     /* convert the nspace/rank to an opal_process_name_t */
 655     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&proc.jobid, p->nspace))) {
 656         return ext3x_convert_opalrc(rc);
 657     }
 658     proc.vpid = ext3x_convert_rank(p->rank);
 659 
 660     /* setup the caddy */
 661     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 662     opalcaddy->spwncbfunc = cbfunc;
 663     opalcaddy->cbdata = cbdata;
 664 
 665     /* convert the job info */
 666     for (k=0; k < ninfo; k++) {
 667         oinfo = OBJ_NEW(opal_value_t);
 668         opal_list_append(&opalcaddy->info, &oinfo->super);
 669         oinfo->key = strdup(job_info[k].key);
 670         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &job_info[k].value))) {
 671             OBJ_RELEASE(opalcaddy);
 672             return ext3x_convert_opalrc(rc);
 673         }
 674     }
 675 
 676     /* convert the apps */
 677     for (n=0; n < napps; n++) {
 678         app = OBJ_NEW(opal_pmix_app_t);
 679         opal_list_append(&opalcaddy->apps, &app->super);
 680         if (NULL != apps[n].cmd) {
 681             app->cmd = strdup(apps[n].cmd);
 682         }
 683         if (NULL != apps[n].argv) {
 684             app->argv = opal_argv_copy(apps[n].argv);
 685         }
 686         if (NULL != apps[n].env) {
 687             app->env = opal_argv_copy(apps[n].env);
 688         }
 689         if (NULL != apps[n].cwd) {
 690             app->cwd = strdup(apps[n].cwd);
 691         }
 692         app->maxprocs = apps[n].maxprocs;
 693         for (k=0; k < apps[n].ninfo; k++) {
 694             oinfo = OBJ_NEW(opal_value_t);
 695             opal_list_append(&app->info, &oinfo->super);
 696             oinfo->key = strdup(apps[n].info[k].key);
 697             if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &apps[n].info[k].value))) {
 698                 OBJ_RELEASE(opalcaddy);
 699                 return ext3x_convert_opalrc(rc);
 700             }
 701         }
 702     }
 703 
 704     /* pass it up */
 705     rc = host_module->spawn(&proc, &opalcaddy->info, &opalcaddy->apps, opal_spncbfunc, opalcaddy);
 706     if (OPAL_SUCCESS != rc) {
 707         OPAL_ERROR_LOG(rc);
 708         OBJ_RELEASE(opalcaddy);
 709     }
 710 
 711     return ext3x_convert_opalrc(rc);
 712 }
 713 
 714 
 715 static pmix_status_t server_connect_fn(const pmix_proc_t procs[], size_t nprocs,
 716                                        const pmix_info_t info[], size_t ninfo,
 717                                        pmix_op_cbfunc_t cbfunc, void *cbdata)
 718 {
 719     int rc;
 720     ext3x_opalcaddy_t *opalcaddy;
 721     opal_namelist_t *nm;
 722     size_t n;
 723     opal_value_t *oinfo;
 724 
 725     if (NULL == host_module || NULL == host_module->connect) {
 726         return PMIX_ERR_NOT_SUPPORTED;
 727     }
 728 
 729     /* setup the caddy */
 730     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 731     opalcaddy->opcbfunc = cbfunc;
 732     opalcaddy->cbdata = cbdata;
 733 
 734     /* convert the array of pmix_proc_t to the list of procs */
 735     for (n=0; n < nprocs; n++) {
 736         nm = OBJ_NEW(opal_namelist_t);
 737         opal_list_append(&opalcaddy->procs, &nm->super);
 738         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) {
 739             OBJ_RELEASE(opalcaddy);
 740             return ext3x_convert_opalrc(rc);
 741         }
 742         nm->name.vpid = ext3x_convert_rank(procs[n].rank);
 743     }
 744 
 745     /* convert the info */
 746     for (n=0; n < ninfo; n++) {
 747         oinfo = OBJ_NEW(opal_value_t);
 748         opal_list_append(&opalcaddy->info, &oinfo->super);
 749         oinfo->key = strdup(info[n].key);
 750         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
 751             OBJ_RELEASE(opalcaddy);
 752             return ext3x_convert_opalrc(rc);
 753         }
 754     }
 755 
 756     /* pass it up */
 757     rc = host_module->connect(&opalcaddy->procs, &opalcaddy->info, opal_opcbfunc, opalcaddy);
 758     if (OPAL_SUCCESS != rc) {
 759         OBJ_RELEASE(opalcaddy);
 760     }
 761 
 762     return ext3x_convert_opalrc(rc);
 763 }
 764 
 765 
 766 static pmix_status_t server_disconnect_fn(const pmix_proc_t procs[], size_t nprocs,
 767                                           const pmix_info_t info[], size_t ninfo,
 768                                           pmix_op_cbfunc_t cbfunc, void *cbdata)
 769 {
 770     int rc;
 771     ext3x_opalcaddy_t *opalcaddy;
 772     opal_namelist_t *nm;
 773     size_t n;
 774     opal_value_t *oinfo;
 775 
 776     if (NULL == host_module || NULL == host_module->disconnect) {
 777         return PMIX_ERR_NOT_SUPPORTED;
 778     }
 779 
 780     /* setup the caddy */
 781     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 782     opalcaddy->opcbfunc = cbfunc;
 783     opalcaddy->cbdata = cbdata;
 784 
 785     /* convert the array of pmix_proc_t to the list of procs */
 786     for (n=0; n < nprocs; n++) {
 787         nm = OBJ_NEW(opal_namelist_t);
 788         opal_list_append(&opalcaddy->procs, &nm->super);
 789         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, procs[n].nspace))) {
 790             OBJ_RELEASE(opalcaddy);
 791             return ext3x_convert_opalrc(rc);
 792         }
 793         nm->name.vpid = ext3x_convert_rank(procs[n].rank);
 794     }
 795 
 796     /* convert the info */
 797     for (n=0; n < ninfo; n++) {
 798         oinfo = OBJ_NEW(opal_value_t);
 799         opal_list_append(&opalcaddy->info, &oinfo->super);
 800         oinfo->key = strdup(info[n].key);
 801         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
 802             OBJ_RELEASE(opalcaddy);
 803             return ext3x_convert_opalrc(rc);
 804         }
 805     }
 806 
 807     /* pass it up */
 808     rc = host_module->disconnect(&opalcaddy->procs, &opalcaddy->info, opal_opcbfunc, opalcaddy);
 809     if (OPAL_SUCCESS != rc) {
 810         OBJ_RELEASE(opalcaddy);
 811     }
 812 
 813     return ext3x_convert_opalrc(rc);
 814 }
 815 
 816 static pmix_status_t server_register_events(pmix_status_t *codes, size_t ncodes,
 817                                             const pmix_info_t info[], size_t ninfo,
 818                                             pmix_op_cbfunc_t cbfunc, void *cbdata)
 819 {
 820     ext3x_opalcaddy_t *opalcaddy;
 821     size_t n;
 822     opal_value_t *oinfo;
 823     int rc;
 824 
 825     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 826                         "%s REGISTER EVENTS",
 827                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
 828 
 829     /* setup the caddy */
 830     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 831     opalcaddy->opcbfunc = cbfunc;
 832     opalcaddy->cbdata = cbdata;
 833 
 834     /* convert the info */
 835     for (n=0; n < ninfo; n++) {
 836         oinfo = OBJ_NEW(opal_value_t);
 837         opal_list_append(&opalcaddy->info, &oinfo->super);
 838         oinfo->key = strdup(info[n].key);
 839         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
 840             OBJ_RELEASE(opalcaddy);
 841             return ext3x_convert_opalrc(rc);
 842         }
 843     }
 844 
 845     /* pass it up */
 846     rc = host_module->register_events(&opalcaddy->info, opal_opcbfunc, opalcaddy);
 847     if (OPAL_SUCCESS != rc) {
 848         OBJ_RELEASE(opalcaddy);
 849     }
 850 
 851     return ext3x_convert_opalrc(rc);
 852 }
 853 
 854 static pmix_status_t server_deregister_events(pmix_status_t *codes, size_t ncodes,
 855                                               pmix_op_cbfunc_t cbfunc, void *cbdata)
 856 {
 857     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 858                         "%s DEREGISTER EVENTS", OPAL_NAME_PRINT(OPAL_PROC_MY_NAME));
 859 
 860     return PMIX_ERR_NOT_SUPPORTED;
 861 }
 862 
 863 static pmix_status_t server_notify_event(pmix_status_t code,
 864                                          const pmix_proc_t *source,
 865                                          pmix_data_range_t range,
 866                                          pmix_info_t info[], size_t ninfo,
 867                                          pmix_op_cbfunc_t cbfunc, void *cbdata)
 868 {
 869     ext3x_opalcaddy_t *opalcaddy;
 870     opal_process_name_t src;
 871     size_t n;
 872     opal_value_t *oinfo;
 873     int rc, status;
 874 
 875     if (NULL == host_module || NULL == host_module->notify_event) {
 876         return PMIX_ERR_NOT_SUPPORTED;
 877     }
 878 
 879     /* setup the caddy */
 880     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 881     opalcaddy->opcbfunc = cbfunc;
 882     opalcaddy->cbdata = cbdata;
 883 
 884     /* convert the code */
 885     status = ext3x_convert_rc(code);
 886 
 887     /* convert the source */
 888     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&src.jobid, source->nspace))) {
 889         OBJ_RELEASE(opalcaddy);
 890         return ext3x_convert_opalrc(rc);
 891     }
 892     src.vpid = ext3x_convert_rank(source->rank);
 893 
 894     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 895                         "%s CLIENT %s CALLED NOTIFY",
 896                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 897                         OPAL_NAME_PRINT(src));
 898 
 899     /* ignore the range for now */
 900 
 901     /* convert the info */
 902     for (n=0; n < ninfo; n++) {
 903         oinfo = OBJ_NEW(opal_value_t);
 904         opal_list_append(&opalcaddy->info, &oinfo->super);
 905         oinfo->key = strdup(info[n].key);
 906         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
 907             OBJ_RELEASE(opalcaddy);
 908             return ext3x_convert_opalrc(rc);
 909         }
 910     }
 911 
 912     /* send it upstairs */
 913     if (OPAL_SUCCESS != (rc = host_module->notify_event(status, &src, &opalcaddy->info,
 914                                                         opal_opcbfunc, opalcaddy))) {
 915         OBJ_RELEASE(opalcaddy);
 916     }
 917     return ext3x_convert_opalrc(rc);
 918 }
 919 
 920 static void _info_rel(void *cbdata)
 921 {
 922     ext3x_opcaddy_t *pcaddy = (ext3x_opcaddy_t*)cbdata;
 923 
 924     OBJ_RELEASE(pcaddy);
 925 }
 926 static void info_cbfunc(int status,
 927                         opal_list_t *info,
 928                         void *cbdata,
 929                         opal_pmix_release_cbfunc_t release_fn,
 930                         void *release_cbdata)
 931 {
 932     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
 933     ext3x_opcaddy_t *pcaddy;
 934     opal_value_t *kv;
 935     size_t n;
 936 
 937     pcaddy = OBJ_NEW(ext3x_opcaddy_t);
 938 
 939     /* convert the status */
 940     pcaddy->status = ext3x_convert_opalrc(status);
 941 
 942     /* convert the list to a pmix_info_t array */
 943     if (NULL != info && 0 < (pcaddy->ninfo = opal_list_get_size(info))) {
 944         PMIX_INFO_CREATE(pcaddy->info, pcaddy->ninfo);
 945         n = 0;
 946         OPAL_LIST_FOREACH(kv, info, opal_value_t) {
 947             (void)opal_string_copy(pcaddy->info[n].key, kv->key, PMIX_MAX_KEYLEN);
 948             ext3x_value_load(&pcaddy->info[n].value, kv);
 949             ++n;
 950         }
 951     }
 952     /* we are done with the incoming data */
 953     if (NULL != release_fn) {
 954         release_fn(release_cbdata);
 955     }
 956 
 957     /* provide the answer downward */
 958     if (NULL != opalcaddy->infocbfunc) {
 959         opalcaddy->infocbfunc(pcaddy->status, pcaddy->info, pcaddy->ninfo,
 960                               opalcaddy->cbdata, _info_rel, pcaddy);
 961     }
 962     OBJ_RELEASE(opalcaddy);
 963 }
 964 
 965 static pmix_status_t server_query(pmix_proc_t *proct,
 966                                   pmix_query_t *queries, size_t nqueries,
 967                                   pmix_info_cbfunc_t cbfunc,
 968                                   void *cbdata)
 969 {
 970     ext3x_opalcaddy_t *opalcaddy;
 971     opal_process_name_t requestor;
 972     int rc;
 973     size_t n, m;
 974     opal_pmix_query_t *q;
 975     opal_value_t *oinfo;
 976 
 977     if (NULL == host_module || NULL == host_module->query) {
 978         return PMIX_ERR_NOT_SUPPORTED;
 979     }
 980 
 981     /* setup the caddy */
 982     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 983     opalcaddy->infocbfunc = cbfunc;
 984     opalcaddy->cbdata = cbdata;
 985 
 986     /* convert the requestor */
 987     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) {
 988         OBJ_RELEASE(opalcaddy);
 989         return ext3x_convert_opalrc(rc);
 990     }
 991     requestor.vpid = ext3x_convert_rank(proct->rank);
 992 
 993     opal_output_verbose(3, opal_pmix_base_framework.framework_output,
 994                         "%s CLIENT %s CALLED QUERY",
 995                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 996                         OPAL_NAME_PRINT(requestor));
 997 
 998     /* convert the queries */
 999     for (n=0; n < nqueries; n++) {
1000         q = OBJ_NEW(opal_pmix_query_t);
1001         /* we "borrow" the info field of the caddy as we and the
1002          * server function both agree on what will be there */
1003         opal_list_append(&opalcaddy->info, &q->super);
1004         q->keys = opal_argv_copy(queries[n].keys);
1005         for (m=0; m < queries[n].nqual; m++) {
1006             oinfo = OBJ_NEW(opal_value_t);
1007             opal_list_append(&q->qualifiers, &oinfo->super);
1008 
1009             if (0 == strcmp(queries[n].qualifiers[m].key, PMIX_NSPACE)) {
1010                 /* must convert this to jobid */
1011                 oinfo->key = strdup(OPAL_PMIX_PROCID);
1012                 if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&oinfo->data.name.jobid, queries[n].qualifiers[m].value.data.string))) {
1013                     OBJ_RELEASE(opalcaddy);
1014                     return ext3x_convert_opalrc(rc);
1015                 }
1016             } else {
1017                 oinfo->key = strdup(queries[n].qualifiers[m].key);
1018                 if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &queries[n].qualifiers[m].value))) {
1019                     OBJ_RELEASE(opalcaddy);
1020                     return ext3x_convert_opalrc(rc);
1021                 }
1022             }
1023         }
1024     }
1025 
1026     /* pass the call upwards */
1027     if (OPAL_SUCCESS != (rc = host_module->query(&requestor,
1028                                                  &opalcaddy->info,
1029                                                  info_cbfunc, opalcaddy))) {
1030         OBJ_RELEASE(opalcaddy);
1031     }
1032 
1033     return ext3x_convert_opalrc(rc);
1034 }
1035 
1036 static void toolcbfunc(int status,
1037                        opal_process_name_t proc,
1038                        void *cbdata)
1039 {
1040     ext3x_opalcaddy_t *opalcaddy = (ext3x_opalcaddy_t*)cbdata;
1041     pmix_status_t rc;
1042     pmix_proc_t p;
1043     opal_ext3x_jobid_trkr_t *job;
1044 
1045     /* convert the status */
1046     rc = ext3x_convert_opalrc(status);
1047 
1048     memset(&p, 0, sizeof(pmix_proc_t));
1049     if (OPAL_SUCCESS == status) {
1050         /* convert the process name */
1051         (void)opal_snprintf_jobid(p.nspace, PMIX_MAX_NSLEN, proc.jobid);
1052         p.rank = ext3x_convert_opalrank(proc.vpid);
1053         /* store this job in our list of known nspaces */
1054         job = OBJ_NEW(opal_ext3x_jobid_trkr_t);
1055         (void)opal_string_copy(job->nspace, p.nspace, PMIX_MAX_NSLEN);
1056         job->jobid = proc.jobid;
1057         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1058         opal_list_append(&mca_pmix_ext3x_component.jobids, &job->super);
1059         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1060     }
1061 
1062     /* pass it down */
1063     if (NULL != opalcaddy->toolcbfunc) {
1064         opalcaddy->toolcbfunc(rc, &p, opalcaddy->cbdata);
1065     }
1066     OBJ_RELEASE(opalcaddy);
1067 }
1068 
1069 static void server_tool_connection(pmix_info_t *info, size_t ninfo,
1070                                    pmix_tool_connection_cbfunc_t cbfunc,
1071                                    void *cbdata)
1072 {
1073     ext3x_opalcaddy_t *opalcaddy;
1074     size_t n;
1075     opal_value_t *oinfo;
1076     int rc;
1077     pmix_status_t err;
1078     opal_ext3x_jobid_trkr_t *job;
1079     bool found;
1080 
1081     /* setup the caddy */
1082     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1083     opalcaddy->toolcbfunc = cbfunc;
1084     opalcaddy->cbdata = cbdata;
1085 
1086     /* convert the info */
1087     for (n=0; n < ninfo; n++) {
1088         oinfo = OBJ_NEW(opal_value_t);
1089         opal_list_append(&opalcaddy->info, &oinfo->super);
1090         oinfo->key = strdup(info[n].key);
1091         if (0 == strncmp(oinfo->key, PMIX_NSPACE, PMIX_MAX_KEYLEN)) {
1092             /* will pass it up as a jobid */
1093             oinfo->type = OPAL_JOBID;
1094             /* see if this job is in our list of known nspaces */
1095             found = false;
1096             OPAL_LIST_FOREACH(job, &mca_pmix_ext3x_component.jobids, opal_ext3x_jobid_trkr_t) {
1097                 if (0 == strncmp(job->nspace, info[n].value.data.proc->nspace, PMIX_MAX_NSLEN)) {
1098                     oinfo->data.name.jobid = job->jobid;
1099                     found = true;
1100                     break;
1101                 }
1102             }
1103             if (!found) {
1104                 if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&oinfo->data.name.jobid, info[n].value.data.proc->nspace))) {
1105                     OPAL_ERROR_LOG(rc);
1106                     OBJ_RELEASE(opalcaddy);
1107                     err = ext3x_convert_opalrc(rc);
1108                     if (NULL != cbfunc) {
1109                         cbfunc(err, NULL, cbdata);
1110                     }
1111                     return;
1112                 }
1113             }
1114         } else if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &info[n].value))) {
1115             OBJ_RELEASE(opalcaddy);
1116             err = ext3x_convert_opalrc(rc);
1117             if (NULL != cbfunc) {
1118                 cbfunc(err, NULL, cbdata);
1119             }
1120             return;
1121         }
1122     }
1123 
1124     /* pass it up */
1125     host_module->tool_connected(&opalcaddy->info, toolcbfunc, opalcaddy);
1126 }
1127 
1128 static void server_log(const pmix_proc_t *proct,
1129                        const pmix_info_t data[], size_t ndata,
1130                        const pmix_info_t directives[], size_t ndirs,
1131                        pmix_op_cbfunc_t cbfunc, void *cbdata)
1132 {
1133     ext3x_opalcaddy_t *opalcaddy;
1134     opal_process_name_t requestor;
1135     int rc;
1136     size_t n;
1137     opal_value_t *oinfo;
1138     pmix_status_t ret;
1139 
1140     if (NULL == host_module || NULL == host_module->log) {
1141         if (NULL != cbfunc) {
1142             cbfunc(PMIX_ERR_NOT_SUPPORTED, cbdata);
1143         }
1144         return;
1145     }
1146 
1147     /* setup the caddy */
1148     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1149     opalcaddy->opcbfunc = cbfunc;
1150     opalcaddy->cbdata = cbdata;
1151 
1152     /* convert the requestor */
1153     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) {
1154     OBJ_RELEASE(opalcaddy);
1155     ret = ext3x_convert_opalrc(rc);
1156         if (NULL != cbfunc) {
1157             cbfunc(ret, cbdata);
1158         }
1159         return;
1160     }
1161     requestor.vpid = ext3x_convert_rank(proct->rank);
1162 
1163     /* convert the data */
1164     for (n=0; n < ndata; n++) {
1165         oinfo = OBJ_NEW(opal_value_t);
1166         oinfo->key = strdup(data[n].key);
1167         /* we "borrow" the info field of the caddy as we and the
1168          * server function both agree on what will be there */
1169         opal_list_append(&opalcaddy->info, &oinfo->super);
1170         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &data[n].value))) {
1171             OBJ_RELEASE(opalcaddy);
1172             ret = ext3x_convert_opalrc(rc);
1173             if (NULL != cbfunc) {
1174                 cbfunc(ret, cbdata);
1175             }
1176             return;
1177         }
1178     }
1179 
1180     /* convert the directives */
1181     for (n=0; n < ndirs; n++) {
1182         oinfo = OBJ_NEW(opal_value_t);
1183         /* we "borrow" the apps field of the caddy as we and the
1184          * server function both agree on what will be there */
1185         opal_list_append(&opalcaddy->apps, &oinfo->super);
1186         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &directives[n].value))) {
1187             OBJ_RELEASE(opalcaddy);
1188             ret = ext3x_convert_opalrc(rc);
1189             if (NULL != cbfunc) {
1190                 cbfunc(ret, cbdata);
1191             }
1192             return;
1193         }
1194     }
1195 
1196     /* pass the call upwards */
1197     host_module->log(&requestor,
1198                      &opalcaddy->info,
1199                      &opalcaddy->apps,
1200                      opal_opcbfunc, opalcaddy);
1201 }
1202 
1203 static pmix_status_t server_allocate(const pmix_proc_t *proct,
1204                                      pmix_alloc_directive_t directive,
1205                                      const pmix_info_t data[], size_t ndata,
1206                                      pmix_info_cbfunc_t cbfunc, void *cbdata)
1207 {
1208     ext3x_opalcaddy_t *opalcaddy;
1209     opal_process_name_t requestor;
1210     int rc;
1211     size_t n;
1212     opal_value_t *oinfo;
1213     opal_pmix_alloc_directive_t odir;
1214 
1215     if (NULL == host_module || NULL == host_module->allocate) {
1216         return PMIX_ERR_NOT_SUPPORTED;
1217     }
1218 
1219     /* setup the caddy */
1220     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1221     opalcaddy->infocbfunc = cbfunc;
1222     opalcaddy->cbdata = cbdata;
1223 
1224     /* convert the requestor */
1225     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) {
1226         OBJ_RELEASE(opalcaddy);
1227         return ext3x_convert_opalrc(rc);
1228     }
1229     requestor.vpid = ext3x_convert_rank(proct->rank);
1230 
1231     /* convert the directive */
1232     odir = ext3x_convert_allocdir(directive);
1233 
1234     /* convert the data */
1235     for (n=0; n < ndata; n++) {
1236         oinfo = OBJ_NEW(opal_value_t);
1237         opal_list_append(&opalcaddy->info, &oinfo->super);
1238         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &data[n].value))) {
1239             OBJ_RELEASE(opalcaddy);
1240             return ext3x_convert_opalrc(rc);
1241         }
1242     }
1243 
1244     /* pass the call upwards */
1245     if (OPAL_SUCCESS != (rc = host_module->allocate(&requestor, odir,
1246                                                     &opalcaddy->info,
1247                                                     info_cbfunc, opalcaddy))) {
1248         OBJ_RELEASE(opalcaddy);
1249         return ext3x_convert_opalrc(rc);
1250     }
1251 
1252     return PMIX_SUCCESS;
1253 
1254 }
1255 
1256 static pmix_status_t server_job_control(const pmix_proc_t *proct,
1257                                         const pmix_proc_t targets[], size_t ntargets,
1258                                         const pmix_info_t directives[], size_t ndirs,
1259                                         pmix_info_cbfunc_t cbfunc, void *cbdata)
1260 {
1261     ext3x_opalcaddy_t *opalcaddy;
1262     opal_process_name_t requestor;
1263     int rc;
1264     size_t n;
1265     opal_value_t *oinfo;
1266     opal_namelist_t *nm;
1267 
1268     if (NULL == host_module || NULL == host_module->job_control) {
1269         return PMIX_ERR_NOT_SUPPORTED;
1270     }
1271 
1272     /* setup the caddy */
1273     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1274     opalcaddy->infocbfunc = cbfunc;
1275     opalcaddy->cbdata = cbdata;
1276 
1277     /* convert the requestor */
1278     if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&requestor.jobid, proct->nspace))) {
1279         OBJ_RELEASE(opalcaddy);
1280         return ext3x_convert_opalrc(rc);
1281     }
1282     requestor.vpid = ext3x_convert_rank(proct->rank);
1283 
1284     /* convert the targets */
1285     for (n=0; n < ntargets; n++) {
1286         nm = OBJ_NEW(opal_namelist_t);
1287         opal_list_append(&opalcaddy->procs, &nm->super);
1288         if (OPAL_SUCCESS != (rc = opal_convert_string_to_jobid(&nm->name.jobid, targets[n].nspace))) {
1289             OBJ_RELEASE(opalcaddy);
1290             return ext3x_convert_opalrc(rc);
1291         }
1292         nm->name.vpid = ext3x_convert_rank(targets[n].rank);
1293     }
1294 
1295     /* convert the directives */
1296     for (n=0; n < ndirs; n++) {
1297         oinfo = OBJ_NEW(opal_value_t);
1298         opal_list_append(&opalcaddy->info, &oinfo->super);
1299         oinfo->key = strdup(directives[n].key);
1300         if (OPAL_SUCCESS != (rc = ext3x_value_unload(oinfo, &directives[n].value))) {
1301             OBJ_RELEASE(opalcaddy);
1302             return ext3x_convert_opalrc(rc);
1303         }
1304     }
1305 
1306     /* pass the call upwards */
1307     if (OPAL_SUCCESS != (rc = host_module->job_control(&requestor,
1308                                                        &opalcaddy->procs,
1309                                                        &opalcaddy->info,
1310                                                        info_cbfunc, opalcaddy))) {
1311         OBJ_RELEASE(opalcaddy);
1312         return ext3x_convert_opalrc(rc);
1313     }
1314 
1315     return PMIX_SUCCESS;
1316 }
1317 
1318 static pmix_status_t server_iof_pull(const pmix_proc_t procs[], size_t nprocs,
1319                                      const pmix_info_t directives[], size_t ndirs,
1320                                      pmix_iof_channel_t channels,
1321                                      pmix_op_cbfunc_t cbfunc, void *cbdata)
1322 {
1323     if (NULL == host_module || NULL == host_module->iof_pull) {
1324         return PMIX_ERR_NOT_SUPPORTED;
1325     }
1326     return PMIX_ERR_NOT_SUPPORTED;
1327 }
1328 
1329 static pmix_status_t server_stdin(const pmix_proc_t *source,
1330                                   const pmix_proc_t targets[], size_t ntargets,
1331                                   const pmix_info_t directives[], size_t ndirs,
1332                                   const pmix_byte_object_t *bo,
1333                                   pmix_op_cbfunc_t cbfunc, void *cbdata)
1334 {
1335     if (NULL == host_module || NULL == host_module->iof_push) {
1336         return PMIX_ERR_NOT_SUPPORTED;
1337     }
1338     return PMIX_ERR_NOT_SUPPORTED;
1339 }

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