This source file includes following definitions.
- opal_opcbfunc
- server_client_connected_fn
- server_client_finalized_fn
- server_abort_fn
- _data_release
- opmdx_response
- server_fencenb_fn
- server_dmodex_req_fn
- server_publish_fn
- opal_lkupcbfunc
- server_lookup_fn
- server_unpublish_fn
- opal_spncbfunc
- server_spawn_fn
- server_connect_fn
- server_disconnect_fn
- server_register_events
- server_deregister_events
- server_notify_event
- _info_rel
- info_cbfunc
- server_query
- toolcbfunc
- server_tool_connection
- server_log
- server_allocate
- server_job_control
- server_iof_pull
- server_stdin
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  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 
  46 
  47 
  48 
  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     
 146 
 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     
 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     
 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     
 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     
 210     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 211     opalcaddy->opcbfunc = cbfunc;
 212     opalcaddy->cbdata = cbdata;
 213 
 214     
 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     
 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     
 253     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 254     opalcaddy->opcbfunc = cbfunc;
 255     opalcaddy->cbdata = cbdata;
 256 
 257     
 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     
 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         
 305 
 306 
 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     
 336     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 337     opalcaddy->mdxcbfunc = cbfunc;
 338     opalcaddy->cbdata = cbdata;
 339 
 340     
 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     
 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     
 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     
 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     
 398     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 399     opalcaddy->mdxcbfunc = cbfunc;
 400     opalcaddy->cbdata = cbdata;
 401 
 402     
 403 
 404 
 405 
 406 
 407 
 408 
 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     
 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     
 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    
 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     
 467     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 468     opalcaddy->opcbfunc = cbfunc;
 469     opalcaddy->cbdata = cbdata;
 470 
 471     
 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     
 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         
 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                 
 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     
 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     
 548     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 549     opalcaddy->lkupcbfunc = cbfunc;
 550     opalcaddy->cbdata = cbdata;
 551 
 552     
 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     
 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     
 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     
 599     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 600     opalcaddy->opcbfunc = cbfunc;
 601     opalcaddy->cbdata = cbdata;
 602 
 603     
 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     
 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         
 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     
 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     
 661     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 662     opalcaddy->spwncbfunc = cbfunc;
 663     opalcaddy->cbdata = cbdata;
 664 
 665     
 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     
 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     
 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     
 730     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 731     opalcaddy->opcbfunc = cbfunc;
 732     opalcaddy->cbdata = cbdata;
 733 
 734     
 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     
 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     
 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     
 781     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 782     opalcaddy->opcbfunc = cbfunc;
 783     opalcaddy->cbdata = cbdata;
 784 
 785     
 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     
 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     
 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     
 830     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 831     opalcaddy->opcbfunc = cbfunc;
 832     opalcaddy->cbdata = cbdata;
 833 
 834     
 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     
 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     
 880     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 881     opalcaddy->opcbfunc = cbfunc;
 882     opalcaddy->cbdata = cbdata;
 883 
 884     
 885     status = ext3x_convert_rc(code);
 886 
 887     
 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     
 900 
 901     
 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     
 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     
 940     pcaddy->status = ext3x_convert_opalrc(status);
 941 
 942     
 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     
 953     if (NULL != release_fn) {
 954         release_fn(release_cbdata);
 955     }
 956 
 957     
 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     
 982     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
 983     opalcaddy->infocbfunc = cbfunc;
 984     opalcaddy->cbdata = cbdata;
 985 
 986     
 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     
 999     for (n=0; n < nqueries; n++) {
1000         q = OBJ_NEW(opal_pmix_query_t);
1001         
1002 
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                 
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     
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     
1046     rc = ext3x_convert_opalrc(status);
1047 
1048     memset(&p, 0, sizeof(pmix_proc_t));
1049     if (OPAL_SUCCESS == status) {
1050         
1051         (void)opal_snprintf_jobid(p.nspace, PMIX_MAX_NSLEN, proc.jobid);
1052         p.rank = ext3x_convert_opalrank(proc.vpid);
1053         
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     
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     
1082     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1083     opalcaddy->toolcbfunc = cbfunc;
1084     opalcaddy->cbdata = cbdata;
1085 
1086     
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             
1093             oinfo->type = OPAL_JOBID;
1094             
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     
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     
1148     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1149     opalcaddy->opcbfunc = cbfunc;
1150     opalcaddy->cbdata = cbdata;
1151 
1152     
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     
1164     for (n=0; n < ndata; n++) {
1165         oinfo = OBJ_NEW(opal_value_t);
1166         oinfo->key = strdup(data[n].key);
1167         
1168 
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     
1181     for (n=0; n < ndirs; n++) {
1182         oinfo = OBJ_NEW(opal_value_t);
1183         
1184 
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     
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     
1220     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1221     opalcaddy->infocbfunc = cbfunc;
1222     opalcaddy->cbdata = cbdata;
1223 
1224     
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     
1232     odir = ext3x_convert_allocdir(directive);
1233 
1234     
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     
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     
1273     opalcaddy = OBJ_NEW(ext3x_opalcaddy_t);
1274     opalcaddy->infocbfunc = cbfunc;
1275     opalcaddy->cbdata = cbdata;
1276 
1277     
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     
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     
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     
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 }