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

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