@@ -270,8 +270,11 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
270270 pmix_status_t rc , ret ;
271271 pmix_value_t * val = NULL ;
272272 int32_t cnt ;
273- pmix_proc_t proc ;
273+ pmix_proc_t proc , proct ;
274+ pmix_byte_object_t bo ;
275+ pmix_buffer_t pbkt ;
274276 pmix_kval_t * kv ;
277+ pmix_peer_t * peer ;
275278
276279 pmix_output_verbose (2 , pmix_globals .debug_output ,
277280 "pmix: get_nb callback recvd" );
@@ -299,9 +302,82 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
299302 if (PMIX_SUCCESS != ret ) {
300303 goto done ;
301304 }
302- PMIX_GDS_ACCEPT_KVS_RESP (rc , pmix_client_globals .myserver , buf );
303- if (PMIX_SUCCESS != rc ) {
304- goto done ;
305+
306+ /* the incoming payload is provided as a set of packed
307+ * byte objects, one for each rank. A pmix_proc_t is the first
308+ * entry in the byte object. If the rank=PMIX_RANK_WILDCARD,
309+ * then that byte object contains job level info
310+ * for the provided nspace. Otherwise, the byte
311+ * object contains the pmix_kval_t's that were "put" by the
312+ * referenced process */
313+ cnt = 1 ;
314+ PMIX_BFROPS_UNPACK (rc , pmix_client_globals .myserver ,
315+ buf , & bo , & cnt , PMIX_BYTE_OBJECT );
316+ while (PMIX_SUCCESS == rc ) {
317+ /* setup the byte object for unpacking */
318+ PMIX_CONSTRUCT (& pbkt , pmix_buffer_t );
319+ PMIX_LOAD_BUFFER (pmix_client_globals .myserver ,
320+ & pbkt , bo .bytes , bo .size );
321+ /* unpack the id of the providing process */
322+ cnt = 1 ;
323+ PMIX_BFROPS_UNPACK (rc , pmix_client_globals .myserver ,
324+ & pbkt , & proct , & cnt , PMIX_PROC );
325+ if (PMIX_SUCCESS != rc ) {
326+ PMIX_ERROR_LOG (rc );
327+ goto done ;
328+ }
329+ /* if the rank is WILDCARD, then the byte object contains
330+ * job-level data. Note that we can get job-level data
331+ * for a "get" request that referenced a specific non-wildcard
332+ * rank - this happens in the case where the nspace is
333+ * different than that of the requestor. We may also be
334+ * in a situation where the data for -all- ranks on a
335+ * remote node is being returned by a request for data
336+ * from only one of them - this can occur as an optimization.
337+ * So we have to check the rank here as it may not match the rank of
338+ * the requestor */
339+ if (PMIX_RANK_WILDCARD == proct .rank ) {
340+ peer = pmix_client_globals .myserver ; // job-level data is accessed via the server module
341+ } else {
342+ peer = pmix_globals .mypeer ; // all other data is stored on my peer module
343+ }
344+ cnt = 1 ;
345+ kv = PMIX_NEW (pmix_kval_t );
346+ PMIX_BFROPS_UNPACK (rc , pmix_client_globals .myserver ,
347+ & pbkt , kv , & cnt , PMIX_KVAL );
348+ while (PMIX_SUCCESS == rc ) {
349+ /* let the GDS component for this peer store it - if
350+ * the kval contains shmem connection info, then the
351+ * component will know what to do about it (or else
352+ * we selected the wrong component for this peer!) */
353+ PMIX_GDS_STORE_KV (rc , peer , & proct , PMIX_INTERNAL , kv );
354+ if (PMIX_SUCCESS != rc ) {
355+ PMIX_ERROR_LOG (rc );
356+ PMIX_RELEASE (kv );
357+ PMIX_DESTRUCT (& pbkt );
358+ goto done ;
359+ }
360+ PMIX_RELEASE (kv ); // maintain accounting
361+ /* get the next one */
362+ kv = PMIX_NEW (pmix_kval_t );
363+ cnt = 1 ;
364+ PMIX_BFROPS_UNPACK (rc , pmix_client_globals .myserver ,
365+ & pbkt , kv , & cnt , PMIX_KVAL );
366+ }
367+ PMIX_RELEASE (kv ); // maintain accounting
368+ if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc ) {
369+ PMIX_ERROR_LOG (rc );
370+ PMIX_DESTRUCT (& pbkt );
371+ goto done ;
372+ }
373+ PMIX_DESTRUCT (& pbkt );
374+ /* get the next one */
375+ cnt = 1 ;
376+ PMIX_BFROPS_UNPACK (rc , pmix_client_globals .myserver ,
377+ buf , & bo , & cnt , PMIX_BYTE_OBJECT );
378+ }
379+ if (PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc ) {
380+ PMIX_ERROR_LOG (rc );
305381 }
306382
307383 done :
@@ -315,7 +391,7 @@ static void _getnb_cbfunc(struct pmix_peer_t *pr,
315391 /* we have the data for this proc - see if we can find the key */
316392 cb -> proc = & proc ;
317393 cb -> scope = PMIX_SCOPE_UNDEF ;
318- /* fetch the data from server peer module - since it is passing
394+ /* fetch the data from my peer module - since we are passing
319395 * it back to the user, we need a copy of it */
320396 cb -> copy = true;
321397 PMIX_GDS_FETCH_KV (rc , pmix_client_globals .myserver , cb );
@@ -410,6 +486,7 @@ static void _getnbfn(int fd, short flags, void *cbdata)
410486 pmix_proc_t proc ;
411487 bool optional = false;
412488 struct timeval tv ;
489+ bool my_nspace = false, my_rank = false;
413490
414491 /* cb was passed to us from another thread - acquire it */
415492 PMIX_ACQUIRE_OBJECT (cb );
@@ -448,13 +525,22 @@ static void _getnbfn(int fd, short flags, void *cbdata)
448525 }
449526 }
450527
451- /* check the internal storage first */
452- cb -> proc = & proc ;
453- cb -> copy = true;
454- PMIX_GDS_FETCH_KV (rc , pmix_globals .mypeer , cb );
455- if (PMIX_SUCCESS == rc ) {
456- rc = process_values (& val , cb );
457- goto respond ;
528+ my_nspace = (0 == strncmp (cb -> pname .nspace , pmix_globals .myid .nspace , PMIX_MAX_NSLEN ));
529+ my_rank = (pmix_globals .myid .rank == cb -> pname .rank );
530+
531+ /* if we are looking for data from ourselves, then
532+ * check the internal storage first */
533+ if (my_rank ) {
534+ cb -> proc = & proc ;
535+ cb -> copy = true;
536+ PMIX_GDS_FETCH_KV (rc , pmix_globals .mypeer , cb );
537+ if (PMIX_SUCCESS == rc ) {
538+ rc = process_values (& val , cb );
539+ goto respond ;
540+ }
541+ if (my_nspace ) {
542+ goto respond ;
543+ }
458544 }
459545
460546 /* if the key is NULL or starts with "pmix", then they are looking
@@ -466,7 +552,7 @@ static void _getnbfn(int fd, short flags, void *cbdata)
466552 cb -> copy = true;
467553 PMIX_GDS_FETCH_KV (rc , pmix_client_globals .myserver , cb );
468554 if (PMIX_SUCCESS != rc ) {
469- if (0 != strncmp ( cb -> pname . nspace , pmix_globals . myid . nspace , PMIX_MAX_NSLEN ) ) {
555+ if (! my_nspace ) {
470556 /* we are asking about the job-level info from another
471557 * namespace. It seems that we don't have it - go and
472558 * ask server
0 commit comments