This source file includes following definitions.
- init
- finalize
- pmix_getline
- connect_to_peer
- send_recv
- send_oneway
- timeout
- parse_uri_file
- try_connect
- send_connect_ack
- recv_connect_ack
- df_search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <src/include/pmix_config.h>
27 #include "src/include/pmix_globals.h"
28
29 #ifdef HAVE_FCNTL_H
30 #include <fcntl.h>
31 #endif
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #ifdef HAVE_SYS_SOCKET_H
36 #include <sys/socket.h>
37 #endif
38 #ifdef HAVE_SYS_UIO_H
39 #include <sys/uio.h>
40 #endif
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47 #ifdef HAVE_DIRENT_H
48 #include <dirent.h>
49 #endif
50 #ifdef HAVE_SYS_SYSCTL_H
51 #include <sys/sysctl.h>
52 #endif
53
54 #include "src/include/pmix_socket_errno.h"
55 #include "src/client/pmix_client_ops.h"
56 #include "src/server/pmix_server_ops.h"
57 #include "src/util/argv.h"
58 #include "src/util/error.h"
59 #include "src/util/os_path.h"
60 #include "src/util/show_help.h"
61 #include "src/mca/bfrops/base/base.h"
62 #include "src/mca/gds/gds.h"
63
64 #include "src/mca/ptl/base/base.h"
65 #include "ptl_tcp.h"
66
67 static pmix_status_t init(void);
68 static void finalize(void);
69 static pmix_status_t connect_to_peer(struct pmix_peer_t *peer,
70 pmix_info_t *info, size_t ninfo);
71 static pmix_status_t send_recv(struct pmix_peer_t *peer,
72 pmix_buffer_t *bfr,
73 pmix_ptl_cbfunc_t cbfunc,
74 void *cbdata);
75 static pmix_status_t send_oneway(struct pmix_peer_t *peer,
76 pmix_buffer_t *bfr,
77 pmix_ptl_tag_t tag);
78
79 pmix_ptl_module_t pmix_ptl_tcp_module = {
80 .init = init,
81 .finalize = finalize,
82 .send_recv = send_recv,
83 .send = send_oneway,
84 .connect_to_peer = connect_to_peer
85 };
86
87 static pmix_status_t recv_connect_ack(int sd, uint8_t myflag);
88 static pmix_status_t send_connect_ack(int sd, uint8_t *myflag, pmix_info_t info[], size_t ninfo);
89
90
91 static pmix_status_t init(void)
92 {
93 return PMIX_SUCCESS;
94 }
95
96 static void finalize(void)
97 {
98 }
99
100 static char *pmix_getline(FILE *fp)
101 {
102 char *ret, *buff;
103 char input[1024];
104
105 ret = fgets(input, 1024, fp);
106 if (NULL != ret) {
107 input[strlen(input)-1] = '\0';
108 buff = strdup(input);
109 return buff;
110 }
111
112 return NULL;
113 }
114
115 static pmix_status_t parse_uri_file(char *filename,
116 char **uri,
117 char **nspace,
118 pmix_rank_t *rank);
119 static pmix_status_t try_connect(char *uri, int *sd, pmix_info_t info[], size_t ninfo);
120 static pmix_status_t df_search(char *dirname, char *prefix,
121 pmix_info_t info[], size_t ninfo,
122 int *sd, char **nspace,
123 pmix_rank_t *rank, char **uri);
124
125 static pmix_status_t connect_to_peer(struct pmix_peer_t *peer,
126 pmix_info_t *info, size_t ninfo)
127 {
128 char *evar, **uri, *suri = NULL, *suri2 = NULL;
129 char *filename, *nspace=NULL;
130 pmix_rank_t rank = PMIX_RANK_WILDCARD;
131 char *p, *p2, *server_nspace = NULL, *rendfile = NULL;
132 int sd, rc;
133 size_t n;
134 char myhost[PMIX_MAXHOSTNAMELEN];
135 bool system_level = false;
136 bool system_level_only = false;
137 bool reconnect = false;
138 pid_t pid = 0, mypid;
139 pmix_list_t ilist;
140 pmix_info_caddy_t *kv;
141 pmix_info_t *iptr = NULL, mypidinfo, mycmdlineinfo, launcher;
142 size_t niptr = 0;
143 pmix_kval_t *urikv = NULL;
144
145 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
146 "ptl:tcp: connecting to server");
147
148
149
150
151
152
153
154 if (PMIX_PROC_IS_CLIENT(pmix_globals.mypeer)) {
155 if (NULL != (evar = getenv("PMIX_SERVER_URI4"))) {
156
157 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V3;
158 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
159 "V3 SERVER DETECTED");
160
161 pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module(NULL);
162 if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) {
163 return PMIX_ERR_INIT;
164 }
165 } else if (NULL != (evar = getenv("PMIX_SERVER_URI3"))) {
166
167 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V3;
168 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
169 "V3 SERVER DETECTED");
170
171 pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module("v3");
172 if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) {
173 return PMIX_ERR_INIT;
174 }
175 } else if (NULL != (evar = getenv("PMIX_SERVER_URI21"))) {
176
177 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V21;
178 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
179 "V21 SERVER DETECTED");
180
181 pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module("v21");
182 if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) {
183 return PMIX_ERR_INIT;
184 }
185 } else if (NULL != (evar = getenv("PMIX_SERVER_URI2"))) {
186
187 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V20;
188 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
189 "V20 SERVER DETECTED");
190
191 pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module("v20");
192 if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) {
193 return PMIX_ERR_INIT;
194 }
195 } else {
196
197 return PMIX_ERR_NOT_SUPPORTED;
198 }
199
200 pmix_client_globals.myserver->nptr->compat.bfrops = pmix_globals.mypeer->nptr->compat.bfrops;
201
202 pmix_globals.mypeer->protocol = PMIX_PROTOCOL_V2;
203
204
205
206
207
208 uri = pmix_argv_split(evar, ';');
209 if (2 != pmix_argv_count(uri)) {
210 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
211 pmix_argv_free(uri);
212 return PMIX_ERR_NOT_SUPPORTED;
213 }
214
215
216 p = uri[0];
217 if (NULL == (p2 = strchr(p, '.'))) {
218 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
219 pmix_argv_free(uri);
220 return PMIX_ERR_NOT_SUPPORTED;
221 }
222 *p2 = '\0';
223 ++p2;
224 nspace = strdup(p);
225 rank = strtoull(p2, NULL, 10);
226 suri = strdup(uri[1]);
227
228 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
229 "ptl:tcp:client attempt connect to %s", uri[1]);
230
231
232 if (PMIX_SUCCESS != (rc = try_connect(uri[1], &sd, info, ninfo))) {
233 free(nspace);
234 pmix_argv_free(uri);
235 free(suri);
236 return rc;
237 }
238 pmix_argv_free(uri);
239 goto complete;
240
241 }
242
243
244
245 suri = NULL;
246 PMIX_CONSTRUCT(&ilist, pmix_list_t);
247 if (NULL != info) {
248 for (n=0; n < ninfo; n++) {
249 if (PMIX_CHECK_KEY(&info[n], PMIX_CONNECT_TO_SYSTEM)) {
250 system_level_only = PMIX_INFO_TRUE(&info[n]);
251 } else if (PMIX_CHECK_KEY(&info[n], PMIX_CONNECT_SYSTEM_FIRST)) {
252
253 system_level = PMIX_INFO_TRUE(&info[n]);
254 } else if (PMIX_CHECK_KEY(&info[n], PMIX_SERVER_PIDINFO)) {
255 pid = info[n].value.data.pid;
256 } else if (PMIX_CHECK_KEY(&info[n], PMIX_SERVER_NSPACE)) {
257 if (NULL != server_nspace) {
258
259 if (0 == strcmp(server_nspace, info[n].value.data.string)) {
260
261 continue;
262 }
263
264 rc = PMIX_ERR_BAD_PARAM;
265 goto cleanup;
266 }
267 server_nspace = strdup(info[n].value.data.string);
268 } else if (PMIX_CHECK_KEY(&info[n], PMIX_SERVER_URI)) {
269 if (NULL != suri) {
270
271 if (0 == strcmp(suri, info[n].value.data.string)) {
272
273 continue;
274 }
275
276 rc = PMIX_ERR_BAD_PARAM;
277 goto cleanup;
278 }
279 suri = strdup(info[n].value.data.string);
280 } else if (PMIX_CHECK_KEY(&info[n], PMIX_CONNECT_RETRY_DELAY)) {
281 mca_ptl_tcp_component.wait_to_connect = info[n].value.data.uint32;
282 } else if (PMIX_CHECK_KEY(&info[n], PMIX_CONNECT_MAX_RETRIES)) {
283 mca_ptl_tcp_component.max_retries = info[n].value.data.uint32;
284 } else if (PMIX_CHECK_KEY(&info[n], PMIX_RECONNECT_SERVER)) {
285 reconnect = true;
286 } else if (PMIX_CHECK_KEY(&info[n], PMIX_LAUNCHER_RENDEZVOUS_FILE)) {
287 if (NULL != rendfile) {
288 free(rendfile);
289 }
290 rendfile = strdup(info[n].value.data.string);
291 } else {
292
293 kv = PMIX_NEW(pmix_info_caddy_t);
294 kv->info = &info[n];
295 pmix_list_append(&ilist, &kv->super);
296 }
297 }
298 }
299
300 kv = PMIX_NEW(pmix_info_caddy_t);
301 mypid = getpid();
302 PMIX_INFO_LOAD(&mypidinfo, PMIX_PROC_PID, &mypid, PMIX_PID);
303 kv->info = &mypidinfo;
304 pmix_list_append(&ilist, &kv->super);
305
306
307 if (PMIX_PROC_IS_LAUNCHER(pmix_globals.mypeer)) {
308 kv = PMIX_NEW(pmix_info_caddy_t);
309 PMIX_INFO_LOAD(&launcher, PMIX_LAUNCHER, NULL, PMIX_BOOL);
310 kv->info = &launcher;
311 pmix_list_append(&ilist, &kv->super);
312 }
313
314
315 #if PMIX_HAVE_APPLE
316 int mib[3], argmax, nargs, num;
317 size_t size;
318 char *procargs, *cp, *cptr;
319 char **stack = NULL;
320
321
322 mib[0] = CTL_KERN;
323 mib[1] = KERN_ARGMAX;
324 size = sizeof(argmax);
325
326 if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) {
327 fprintf(stderr, "sysctl() argmax failed\n");
328 rc = PMIX_ERR_NO_PERMISSIONS;
329 goto cleanup;
330 }
331
332
333 procargs = (char *)malloc(argmax);
334 if (procargs == NULL) {
335 rc = -1;
336 goto cleanup;
337 }
338
339
340 mib[0] = CTL_KERN;
341 mib[1] = KERN_PROCARGS2;
342 mib[2] = getpid();
343
344 size = (size_t)argmax;
345
346 if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) {
347 fprintf(stderr, "Lacked permissions\n");;
348 rc = PMIX_ERR_NO_PERMISSIONS;
349 goto cleanup;
350 }
351
352 memcpy(&nargs, procargs, sizeof(nargs));
353
354 cp = procargs + sizeof(nargs);
355 cp += strlen(cp);
356
357 pmix_argv_append_nosize(&stack, cp);
358
359 while (cp < &procargs[size] && '\0' == *cp) {
360 ++cp;
361 }
362 if (cp != &procargs[size]) {
363
364 cptr = cp;
365 num = 0;
366 while (cp < &procargs[size] && num < nargs) {
367 if ('\0' == *cp) {
368 pmix_argv_append_nosize(&stack, cptr);
369 ++cp;
370 cptr = cp;
371 ++num;
372 } else {
373 ++cp;
374 }
375 }
376 }
377 p = pmix_argv_join(stack, ' ');
378 pmix_argv_free(stack);
379 free(procargs);
380 #else
381 char tmp[512];
382 FILE *fp;
383
384
385 snprintf(tmp, 512, "/proc/%lu/cmdline", (unsigned long)mypid);
386 fp = fopen(tmp, "r");
387 if (NULL != fp) {
388
389 fgets(tmp, 512, fp);
390 fclose(fp);
391 p = strdup(tmp);
392 }
393 #endif
394
395 kv = PMIX_NEW(pmix_info_caddy_t);
396 PMIX_INFO_LOAD(&mycmdlineinfo, PMIX_CMD_LINE, p, PMIX_STRING);
397 kv->info = &mycmdlineinfo;
398 pmix_list_append(&ilist, &kv->super);
399 free(p);
400
401
402 if (0 < (niptr = pmix_list_get_size(&ilist))) {
403 PMIX_INFO_CREATE(iptr, niptr);
404 n = 0;
405 while (NULL != (kv = (pmix_info_caddy_t*)pmix_list_remove_first(&ilist))) {
406 PMIX_INFO_XFER(&iptr[n], kv->info);
407 PMIX_RELEASE(kv);
408 ++n;
409 }
410 }
411 PMIX_LIST_DESTRUCT(&ilist);
412
413 if (NULL == suri && !reconnect && NULL != mca_ptl_tcp_component.super.uri) {
414 suri = strdup(mca_ptl_tcp_component.super.uri);
415 }
416
417
418 pmix_globals.mypeer->protocol = PMIX_PROTOCOL_V2;
419 gethostname(myhost, sizeof(myhost));
420
421 if (NULL != suri) {
422
423
424 if (0 == strncmp(suri, "file:", 5)) {
425 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
426 "ptl:tcp:tool getting connection info from %s", suri);
427 nspace = NULL;
428 rc = parse_uri_file(&suri[5], &suri2, &nspace, &rank);
429 if (PMIX_SUCCESS != rc) {
430 rc = PMIX_ERR_UNREACH;
431 goto cleanup;
432 }
433 free(suri);
434 suri = suri2;
435 } else {
436
437 p = strchr(suri, ';');
438 if (NULL == p) {
439 rc = PMIX_ERR_BAD_PARAM;
440 goto cleanup;
441 }
442 *p = '\0';
443 p++;
444 suri2 = strdup(p);
445
446
447 p = strchr(suri, '.');
448 if (NULL == p) {
449 free(suri2);
450 rc = PMIX_ERR_BAD_PARAM;
451 goto cleanup;
452 }
453 *p = '\0';
454 p++;
455 nspace = strdup(suri);
456 rank = strtoull(p, NULL, 10);
457 free(suri);
458 suri = suri2;
459
460 }
461 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
462 "ptl:tcp:tool attempt connect using given URI %s", suri);
463
464 if (PMIX_SUCCESS != (rc = try_connect(suri, &sd, iptr, niptr))) {
465 goto cleanup;
466 }
467
468 goto complete;
469 }
470
471
472 if (NULL != rendfile) {
473
474 rc = parse_uri_file(rendfile, &suri, &nspace, &rank);
475 free(rendfile);
476 rendfile = NULL;
477 if (PMIX_SUCCESS == rc) {
478 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
479 "ptl:tcp:tool attempt connect to system server at %s", suri);
480
481 if (PMIX_SUCCESS == try_connect(suri, &sd, iptr, niptr)) {
482
483 if (NULL != iptr) {
484 PMIX_INFO_FREE(iptr, niptr);
485 }
486 goto complete;
487 }
488 }
489
490
491 rc = PMIX_ERR_UNREACH;
492 goto cleanup;
493 }
494
495
496 if (system_level || system_level_only) {
497 if (0 > asprintf(&filename, "%s/pmix.sys.%s", mca_ptl_tcp_component.system_tmpdir, myhost)) {
498 rc = PMIX_ERR_NOMEM;
499 goto cleanup;
500 }
501 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
502 "ptl:tcp:tool looking for system server at %s",
503 filename);
504
505 rc = parse_uri_file(filename, &suri, &nspace, &rank);
506 free(filename);
507 if (PMIX_SUCCESS == rc) {
508 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
509 "ptl:tcp:tool attempt connect to system server at %s", suri);
510
511 if (PMIX_SUCCESS == try_connect(suri, &sd, iptr, niptr)) {
512
513 goto complete;
514 }
515 free(nspace);
516 nspace = NULL;
517 }
518 }
519
520
521
522
523 if (system_level_only) {
524 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
525 "ptl:tcp: connecting to system failed");
526 rc = PMIX_ERR_UNREACH;
527 goto cleanup;
528 }
529
530
531 if (0 != pid) {
532 if (0 > asprintf(&filename, "pmix.%s.tool.%d", myhost, pid)) {
533 rc = PMIX_ERR_NOMEM;
534 goto cleanup;
535 }
536 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
537 "ptl:tcp:tool searching for given session server %s",
538 filename);
539 nspace = NULL;
540 rc = df_search(mca_ptl_tcp_component.system_tmpdir,
541 filename, iptr, niptr, &sd, &nspace, &rank, &suri);
542 free(filename);
543 if (PMIX_SUCCESS == rc) {
544 goto complete;
545 }
546
547
548 rc = PMIX_ERR_UNREACH;
549 goto cleanup;
550 }
551
552
553 if (NULL != server_nspace) {
554 if (0 > asprintf(&filename, "pmix.%s.tool.%s", myhost, server_nspace)) {
555 rc = PMIX_ERR_NOMEM;
556 goto cleanup;
557 }
558 free(server_nspace);
559 server_nspace = NULL;
560 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
561 "ptl:tcp:tool searching for given session server %s",
562 filename);
563 nspace = NULL;
564 rc = df_search(mca_ptl_tcp_component.system_tmpdir,
565 filename, iptr, niptr, &sd, &nspace, &rank, &suri);
566 free(filename);
567 if (PMIX_SUCCESS == rc) {
568 goto complete;
569 }
570
571
572 rc = PMIX_ERR_UNREACH;
573 goto cleanup;
574 }
575
576
577
578
579
580
581 if (0 > asprintf(&filename, "pmix.%s.tool", myhost)) {
582 rc = PMIX_ERR_NOMEM;
583 goto cleanup;
584 }
585 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
586 "ptl:tcp:tool searching for session server %s",
587 filename);
588 nspace = NULL;
589 rc = df_search(mca_ptl_tcp_component.system_tmpdir,
590 filename, iptr, niptr, &sd, &nspace, &rank, &suri);
591 free(filename);
592 if (PMIX_SUCCESS != rc) {
593 rc = PMIX_ERR_UNREACH;
594 goto cleanup;
595 }
596
597 complete:
598 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
599 "tcp_peer_try_connect: Connection across to server succeeded");
600
601
602 if (NULL == nspace || PMIX_RANK_WILDCARD == rank) {
603 CLOSE_THE_SOCKET(sd);
604 rc = PMIX_ERR_UNREACH;
605 goto cleanup;
606 }
607
608 pmix_globals.connected = true;
609 pmix_client_globals.myserver->sd = sd;
610
611
612
613 if (PMIX_PROC_IS_CLIENT(pmix_globals.mypeer)) {
614
615 if (NULL == pmix_client_globals.myserver->info) {
616 pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t);
617 }
618 if (NULL == pmix_client_globals.myserver->nptr) {
619 pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_namespace_t);
620 }
621 if (NULL != pmix_client_globals.myserver->nptr->nspace) {
622 free(pmix_client_globals.myserver->nptr->nspace);
623 }
624 pmix_client_globals.myserver->nptr->nspace = strdup(nspace);
625
626 if (NULL != pmix_client_globals.myserver->info->pname.nspace) {
627 free(pmix_client_globals.myserver->info->pname.nspace);
628 }
629 pmix_client_globals.myserver->info->pname.nspace = strdup(pmix_client_globals.myserver->nptr->nspace);
630 pmix_client_globals.myserver->info->pname.rank = rank;
631 }
632
633 urikv = PMIX_NEW(pmix_kval_t);
634 urikv->key = strdup(PMIX_SERVER_URI);
635 PMIX_VALUE_CREATE(urikv->value, 1);
636 urikv->value->type = PMIX_STRING;
637 asprintf(&urikv->value->data.string, "%s.%u;%s", nspace, rank, suri);
638 PMIX_GDS_STORE_KV(rc, pmix_globals.mypeer,
639 &pmix_globals.myid, PMIX_INTERNAL,
640 urikv);
641 PMIX_RELEASE(urikv);
642
643 pmix_ptl_base_set_nonblocking(sd);
644
645
646 pmix_event_assign(&pmix_client_globals.myserver->recv_event,
647 pmix_globals.evbase,
648 pmix_client_globals.myserver->sd,
649 EV_READ | EV_PERSIST,
650 pmix_ptl_base_recv_handler, pmix_client_globals.myserver);
651 pmix_client_globals.myserver->recv_ev_active = true;
652 PMIX_POST_OBJECT(pmix_client_globals.myserver);
653 pmix_event_add(&pmix_client_globals.myserver->recv_event, 0);
654
655
656 pmix_event_assign(&pmix_client_globals.myserver->send_event,
657 pmix_globals.evbase,
658 pmix_client_globals.myserver->sd,
659 EV_WRITE|EV_PERSIST,
660 pmix_ptl_base_send_handler, pmix_client_globals.myserver);
661 pmix_client_globals.myserver->send_ev_active = false;
662
663 cleanup:
664 if (NULL != nspace) {
665 free(nspace);
666 }
667 if (NULL != iptr) {
668 PMIX_INFO_FREE(iptr, niptr);
669 }
670 if (NULL != rendfile) {
671 free(rendfile);
672 }
673 if (NULL != suri) {
674 free(suri);
675 }
676 if (NULL != server_nspace) {
677 free(server_nspace);
678 }
679 return rc;
680 }
681
682 static pmix_status_t send_recv(struct pmix_peer_t *peer,
683 pmix_buffer_t *bfr,
684 pmix_ptl_cbfunc_t cbfunc,
685 void *cbdata)
686 {
687 pmix_ptl_sr_t *ms;
688 pmix_peer_t *pr = (pmix_peer_t*)peer;
689
690 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
691 "[%s:%d] post send to server",
692 __FILE__, __LINE__);
693
694 ms = PMIX_NEW(pmix_ptl_sr_t);
695 PMIX_RETAIN(pr);
696 ms->peer = pr;
697 ms->bfr = bfr;
698 ms->cbfunc = cbfunc;
699 ms->cbdata = cbdata;
700 PMIX_THREADSHIFT(ms, pmix_ptl_base_send_recv);
701 return PMIX_SUCCESS;
702 }
703
704 static pmix_status_t send_oneway(struct pmix_peer_t *peer,
705 pmix_buffer_t *bfr,
706 pmix_ptl_tag_t tag)
707 {
708 pmix_ptl_queue_t *q;
709 pmix_peer_t *pr = (pmix_peer_t*)peer;
710
711
712
713
714 q = PMIX_NEW(pmix_ptl_queue_t);
715 PMIX_RETAIN(pr);
716 q->peer = pr;
717 q->buf = bfr;
718 q->tag = tag;
719 PMIX_THREADSHIFT(q, pmix_ptl_base_send);
720 return PMIX_SUCCESS;
721 }
722
723 static void timeout(int sd, short args, void *cbdata)
724 {
725 pmix_lock_t *lock = (pmix_lock_t*)cbdata;
726 PMIX_WAKEUP_THREAD(lock);
727 }
728
729
730 static pmix_status_t parse_uri_file(char *filename,
731 char **uri,
732 char **nspace,
733 pmix_rank_t *rank)
734 {
735 FILE *fp;
736 char *srvr, *p, *p2;
737 pmix_lock_t lock;
738 pmix_event_t ev;
739 struct timeval tv;
740 int retries;
741 int major;
742
743 fp = fopen(filename, "r");
744 if (NULL == fp) {
745
746
747
748
749 if (0 != access(filename, R_OK)) {
750 if (ENOENT == errno && 0 < mca_ptl_tcp_component.wait_to_connect) {
751
752
753
754 retries = 0;
755 do {
756 ++retries;
757 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
758 "WAITING FOR CONNECTION FILE");
759 PMIX_CONSTRUCT_LOCK(&lock);
760 tv.tv_sec = mca_ptl_tcp_component.wait_to_connect;
761 tv.tv_usec = 0;
762 pmix_event_evtimer_set(pmix_globals.evbase, &ev,
763 timeout, &lock);
764 pmix_event_evtimer_add(&ev, &tv);
765 PMIX_WAIT_THREAD(&lock);
766 PMIX_DESTRUCT_LOCK(&lock);
767 fp = fopen(filename, "r");
768 if (NULL != fp) {
769
770 goto process;
771 }
772 } while (retries < mca_ptl_tcp_component.max_retries);
773
774 }
775 }
776 return PMIX_ERR_UNREACH;
777 }
778
779 process:
780
781 srvr = pmix_getline(fp);
782 if (NULL == srvr) {
783 PMIX_ERROR_LOG(PMIX_ERR_FILE_READ_FAILURE);
784 fclose(fp);
785 return PMIX_ERR_UNREACH;
786 }
787
788 p2 = pmix_getline(fp);
789 if (NULL == p2) {
790 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V20;
791 pmix_client_globals.myserver->protocol = PMIX_PROTOCOL_V2;
792 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
793 "V20 SERVER DETECTED");
794 } else {
795
796 if ('v' == p2[0]) {
797 major = strtoul(&p2[1], NULL, 10);
798 } else {
799 major = strtoul(p2, NULL, 10);
800 }
801 if (2 == major) {
802 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V21;
803 pmix_client_globals.myserver->protocol = PMIX_PROTOCOL_V2;
804 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
805 "V21 SERVER DETECTED");
806 } else if (3 <= major) {
807 pmix_client_globals.myserver->proc_type = PMIX_PROC_SERVER | PMIX_PROC_V3;
808 pmix_client_globals.myserver->protocol = PMIX_PROTOCOL_V2;
809 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
810 "V3 SERVER DETECTED");
811 }
812 }
813 if (NULL != p2) {
814 free(p2);
815 }
816
817 fclose(fp);
818
819 if (NULL == (p = strchr(srvr, ';'))) {
820
821 free(srvr);
822 return PMIX_ERR_UNREACH;
823 }
824 *p = '\0';
825 ++p;
826
827 if (NULL == (p2 = strchr(srvr, '.'))) {
828
829 free(srvr);
830 return PMIX_ERR_UNREACH;
831 }
832 *p2 = '\0';
833 ++p2;
834
835 *nspace = strdup(srvr);
836 *rank = strtoull(p2, NULL, 10);
837
838
839 *uri = strdup(p);
840 free(srvr);
841
842 return PMIX_SUCCESS;
843 }
844
845 static pmix_status_t try_connect(char *uri, int *sd, pmix_info_t iptr[], size_t niptr)
846 {
847 char *p, *p2, *host;
848 struct sockaddr_in *in;
849 struct sockaddr_in6 *in6;
850 size_t len;
851 pmix_status_t rc;
852 int retries = 0;
853 uint8_t myflag;
854
855 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
856 "pmix:tcp try connect to %s", uri);
857
858
859 pmix_client_globals.myserver->nptr->compat.ptl = &pmix_ptl_tcp_module;
860
861
862 memset(&mca_ptl_tcp_component.connection, 0, sizeof(struct sockaddr_storage));
863 if (0 == strncmp(uri, "tcp4", 4)) {
864
865 p = strdup(&uri[7]);
866 if (NULL == p) {
867 PMIX_ERROR_LOG(PMIX_ERR_NOMEM);
868 return PMIX_ERR_NOMEM;
869 }
870
871
872 p2 = strchr(p, ':');
873 if (NULL == p2) {
874 free(p);
875 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
876 return PMIX_ERR_BAD_PARAM;
877 }
878 *p2 = '\0';
879 p2++;
880 host = p;
881
882 in = (struct sockaddr_in*)&mca_ptl_tcp_component.connection;
883 in->sin_family = AF_INET;
884 in->sin_addr.s_addr = inet_addr(host);
885 if (in->sin_addr.s_addr == INADDR_NONE) {
886 free(p);
887 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
888 return PMIX_ERR_BAD_PARAM;
889 }
890 in->sin_port = htons(atoi(p2));
891 len = sizeof(struct sockaddr_in);
892 } else {
893
894 p = strdup(&uri[7]);
895 if (NULL == p) {
896 PMIX_ERROR_LOG(PMIX_ERR_NOMEM);
897 return PMIX_ERR_NOMEM;
898 }
899
900 p2 = strchr(p, ':');
901 if (NULL == p2) {
902 free(p);
903 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
904 return PMIX_ERR_BAD_PARAM;
905 }
906 *p2 = '\0';
907 if (']' == p[strlen(p)-1]) {
908 p[strlen(p)-1] = '\0';
909 }
910 if ('[' == p[0]) {
911 host = &p[1];
912 } else {
913 host = &p[0];
914 }
915
916 in6 = (struct sockaddr_in6*)&mca_ptl_tcp_component.connection;
917 in6->sin6_family = AF_INET6;
918 if (0 == inet_pton(AF_INET6, host, (void*)&in6->sin6_addr)) {
919 pmix_output (0, "ptl_tcp_parse_uri: Could not convert %s\n", host);
920 free(p);
921 PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
922 return PMIX_ERR_BAD_PARAM;
923 }
924 in6->sin6_port = htons(atoi(p2));
925 len = sizeof(struct sockaddr_in6);
926 }
927 free(p);
928
929 retry:
930
931 if (PMIX_SUCCESS != (rc = pmix_ptl_base_connect(&mca_ptl_tcp_component.connection, len, sd))) {
932
933 return rc;
934 }
935
936
937 if (PMIX_SUCCESS != (rc = send_connect_ack(*sd, &myflag, iptr, niptr))) {
938 PMIX_ERROR_LOG(rc);
939 CLOSE_THE_SOCKET(*sd);
940 return rc;
941 }
942
943
944 if (PMIX_SUCCESS != (rc = recv_connect_ack(*sd, myflag))) {
945 CLOSE_THE_SOCKET(*sd);
946 if (PMIX_ERR_TEMP_UNAVAILABLE == rc) {
947 ++retries;
948 if( retries < mca_ptl_tcp_component.handshake_max_retries ) {
949 goto retry;
950 }
951 }
952 return rc;
953 }
954
955 return PMIX_SUCCESS;
956 }
957 static pmix_status_t send_connect_ack(int sd, uint8_t *myflag,
958 pmix_info_t iptr[], size_t niptr)
959 {
960 char *msg;
961 pmix_ptl_hdr_t hdr;
962 size_t sdsize=0, csize=0;
963 pmix_byte_object_t cred;
964 char *sec, *bfrops, *gds;
965 pmix_bfrop_buffer_type_t bftype;
966 pmix_status_t rc;
967 uint8_t flag;
968 uid_t euid;
969 gid_t egid;
970 uint32_t u32;
971 pmix_buffer_t buf;
972
973 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
974 "pmix:tcp SEND CONNECT ACK");
975
976
977 if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer) &&
978 !PMIX_PROC_IS_LAUNCHER(pmix_globals.mypeer)) {
979 PMIX_ERROR_LOG(PMIX_ERR_NOT_SUPPORTED);
980 return PMIX_ERR_NOT_SUPPORTED;
981 }
982
983
984 memset(&hdr, 0, sizeof(pmix_ptl_hdr_t));
985 hdr.pindex = -1;
986 hdr.tag = UINT32_MAX;
987
988
989
990
991
992
993 PMIX_BYTE_OBJECT_CONSTRUCT(&cred);
994 PMIX_PSEC_CREATE_CRED(rc, pmix_globals.mypeer,
995 NULL, 0, NULL, 0, &cred);
996 if (PMIX_SUCCESS != rc) {
997 return rc;
998 }
999
1000
1001 sdsize = 1;
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 if (PMIX_PROC_IS_LAUNCHER(pmix_globals.mypeer)) {
1017 if (PMIX_PROC_IS_CLIENT(pmix_globals.mypeer)) {
1018
1019
1020 flag = 8;
1021
1022 sdsize += 2*sizeof(uint32_t);
1023
1024 sdsize += strlen(pmix_globals.myid.nspace) + 1 + sizeof(uint32_t);
1025 } else {
1026
1027 sdsize += 2*sizeof(uint32_t);
1028
1029 if (0 < strlen(pmix_globals.myid.nspace) &&
1030 PMIX_RANK_INVALID != pmix_globals.myid.rank) {
1031 flag = 7;
1032 sdsize += strlen(pmix_globals.myid.nspace) + 1 + sizeof(uint32_t);
1033 } else {
1034 flag = 6;
1035 }
1036 }
1037
1038 } else if (PMIX_PROC_IS_CLIENT(pmix_globals.mypeer) &&
1039 !PMIX_PROC_IS_TOOL(pmix_globals.mypeer)) {
1040
1041 flag = 0;
1042
1043 sdsize += strlen(pmix_globals.myid.nspace) + 1 + sizeof(uint32_t);
1044
1045 } else {
1046
1047 sdsize += 2*sizeof(uint32_t);
1048 if (PMIX_PROC_IS_CLIENT(pmix_globals.mypeer)) {
1049
1050
1051 flag = 5;
1052
1053 sdsize += strlen(pmix_globals.myid.nspace) + 1 + sizeof(uint32_t);
1054 } else if (0 < strlen(pmix_globals.myid.nspace) &&
1055 PMIX_RANK_INVALID != pmix_globals.myid.rank) {
1056
1057 sdsize += strlen(pmix_globals.myid.nspace) + 1 + sizeof(uint32_t);
1058 flag = 4;
1059 } else {
1060
1061 flag = 3;
1062 }
1063 }
1064 *myflag = flag;
1065
1066
1067
1068 sec = pmix_globals.mypeer->nptr->compat.psec->name;
1069
1070
1071 bfrops = pmix_globals.mypeer->nptr->compat.bfrops->version;
1072
1073 bftype = pmix_globals.mypeer->nptr->compat.type;
1074
1075
1076 gds = (char*)pmix_client_globals.myserver->nptr->compat.gds->name;
1077
1078
1079 PMIX_CONSTRUCT(&buf, pmix_buffer_t);
1080 if (NULL != iptr) {
1081 PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &buf, &niptr, 1, PMIX_SIZE);
1082 PMIX_BFROPS_PACK(rc, pmix_globals.mypeer, &buf, iptr, niptr, PMIX_INFO);
1083 }
1084
1085
1086
1087 hdr.nbytes = sdsize + strlen(PMIX_VERSION) + 1 + strlen(sec) + 1 \
1088 + strlen(bfrops) + 1 + sizeof(bftype) \
1089 + strlen(gds) + 1 + sizeof(uint32_t) + cred.size \
1090 + buf.bytes_used;
1091
1092
1093 sdsize = (sizeof(hdr) + hdr.nbytes);
1094 if (NULL == (msg = (char*)malloc(sdsize))) {
1095 PMIX_BYTE_OBJECT_DESTRUCT(&cred);
1096 free(sec);
1097 PMIX_DESTRUCT(&buf);
1098 return PMIX_ERR_OUT_OF_RESOURCE;
1099 }
1100 memset(msg, 0, sdsize);
1101
1102
1103 csize=0;
1104 memcpy(msg, &hdr, sizeof(pmix_ptl_hdr_t));
1105 csize += sizeof(pmix_ptl_hdr_t);
1106
1107
1108 memcpy(msg+csize, sec, strlen(sec));
1109 csize += strlen(sec)+1;
1110
1111
1112
1113
1114 u32 = htonl((uint32_t)cred.size);
1115 memcpy(msg+csize, &u32, sizeof(uint32_t));
1116 csize += sizeof(uint32_t);
1117
1118 if (0 < u32) {
1119 memcpy(msg+csize, cred.bytes, cred.size);
1120 csize += cred.size;
1121 }
1122 PMIX_BYTE_OBJECT_DESTRUCT(&cred);
1123
1124
1125
1126 memcpy(msg+csize, &flag, 1);
1127 csize += 1;
1128
1129 if (0 == flag) {
1130
1131 memcpy(msg+csize, pmix_globals.myid.nspace, strlen(pmix_globals.myid.nspace));
1132 csize += strlen(pmix_globals.myid.nspace)+1;
1133
1134 u32 = htonl((uint32_t)pmix_globals.myid.rank);
1135 memcpy(msg+csize, &u32, sizeof(uint32_t));
1136 csize += sizeof(uint32_t);
1137 } else if (3 == flag || 6 == flag) {
1138
1139 euid = geteuid();
1140 u32 = htonl(euid);
1141 memcpy(msg+csize, &u32, sizeof(uint32_t));
1142 csize += sizeof(uint32_t);
1143 egid = getegid();
1144 u32 = htonl(egid);
1145 memcpy(msg+csize, &u32, sizeof(uint32_t));
1146 csize += sizeof(uint32_t);
1147 } else if (4 == flag || 5 == flag || 7 == flag || 8 == flag) {
1148
1149 euid = geteuid();
1150 u32 = htonl(euid);
1151 memcpy(msg+csize, &u32, sizeof(uint32_t));
1152 csize += sizeof(uint32_t);
1153 egid = getegid();
1154 u32 = htonl(egid);
1155 memcpy(msg+csize, &u32, sizeof(uint32_t));
1156 csize += sizeof(uint32_t);
1157
1158 memcpy(msg+csize, pmix_globals.myid.nspace, strlen(pmix_globals.myid.nspace));
1159 csize += strlen(pmix_globals.myid.nspace)+1;
1160
1161 u32 = htonl((uint32_t)pmix_globals.myid.rank);
1162 memcpy(msg+csize, &u32, sizeof(uint32_t));
1163 csize += sizeof(uint32_t);
1164 } else {
1165
1166 PMIX_DESTRUCT(&buf);
1167 return PMIX_ERR_NOT_SUPPORTED;
1168 }
1169
1170
1171 memcpy(msg+csize, PMIX_VERSION, strlen(PMIX_VERSION));
1172 csize += strlen(PMIX_VERSION)+1;
1173
1174
1175 memcpy(msg+csize, bfrops, strlen(bfrops));
1176 csize += strlen(bfrops)+1;
1177
1178
1179 memcpy(msg+csize, &bftype, sizeof(bftype));
1180 csize += sizeof(bftype);
1181
1182
1183 memcpy(msg+csize, gds, strlen(gds));
1184 csize += strlen(gds)+1;
1185
1186
1187 memcpy(msg+csize, buf.base_ptr, buf.bytes_used);
1188 csize += buf.bytes_used;
1189
1190
1191 if (PMIX_SUCCESS != pmix_ptl_base_send_blocking(sd, msg, sdsize)) {
1192 free(msg);
1193 PMIX_DESTRUCT(&buf);
1194 return PMIX_ERR_UNREACH;
1195 }
1196 free(msg);
1197 PMIX_DESTRUCT(&buf);
1198 return PMIX_SUCCESS;
1199 }
1200
1201
1202
1203
1204 static pmix_status_t recv_connect_ack(int sd, uint8_t myflag)
1205 {
1206 pmix_status_t reply;
1207 pmix_status_t rc;
1208 struct timeval tv, save;
1209 pmix_socklen_t sz;
1210 bool sockopt = true;
1211 pmix_nspace_t nspace;
1212 uint32_t u32;
1213
1214 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1215 "pmix: RECV CONNECT ACK FROM SERVER");
1216
1217
1218 sz = sizeof(save);
1219 if (0 != getsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (void*)&save, &sz)) {
1220 if (ENOPROTOOPT == errno || EOPNOTSUPP == errno) {
1221 sockopt = false;
1222 } else {
1223 return PMIX_ERR_UNREACH;
1224 }
1225 } else {
1226
1227 tv.tv_sec = mca_ptl_tcp_component.handshake_wait_time;
1228 tv.tv_usec = 0;
1229 if (0 != setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) {
1230 if (ENOPROTOOPT == errno || EOPNOTSUPP == errno) {
1231 sockopt = false;
1232 } else {
1233 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1234 "pmix: recv_connect_ack could not setsockopt SO_RCVTIMEO");
1235 return PMIX_ERR_UNREACH;
1236 }
1237 }
1238 }
1239
1240
1241 rc = pmix_ptl_base_recv_blocking(sd, (char*)&u32, sizeof(uint32_t));
1242 if (PMIX_SUCCESS != rc) {
1243 if (sockopt) {
1244
1245 if (0 != setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &save, sz)) {
1246 return PMIX_ERR_UNREACH;
1247 }
1248 }
1249 return rc;
1250 }
1251 reply = ntohl(u32);
1252
1253 if (0 == myflag) {
1254
1255 if (PMIX_ERR_READY_FOR_HANDSHAKE == reply) {
1256 PMIX_PSEC_CLIENT_HANDSHAKE(rc, pmix_client_globals.myserver, sd);
1257 if (PMIX_SUCCESS != rc) {
1258 return rc;
1259 }
1260 } else if (PMIX_SUCCESS != reply) {
1261 return reply;
1262 }
1263 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1264 "pmix: RECV CONNECT CONFIRMATION");
1265
1266
1267 rc = pmix_ptl_base_recv_blocking(sd, (char*)&u32, sizeof(uint32_t));
1268 if (PMIX_SUCCESS != rc) {
1269 return rc;
1270 }
1271 pmix_globals.pindex = ntohl(u32);
1272 } else {
1273
1274 if (PMIX_SUCCESS != reply) {
1275 return reply;
1276 }
1277
1278 if (3 == myflag || 6 == myflag) {
1279
1280 rc = pmix_ptl_base_recv_blocking(sd, (char*)&nspace, PMIX_MAX_NSLEN+1);
1281 if (PMIX_SUCCESS != rc) {
1282 return rc;
1283 }
1284 PMIX_LOAD_NSPACE(pmix_globals.myid.nspace, nspace);
1285
1286 rc = pmix_ptl_base_recv_blocking(sd, (char*)&u32, sizeof(uint32_t));
1287 if (PMIX_SUCCESS != rc) {
1288 return rc;
1289 }
1290
1291 pmix_globals.myid.rank = htonl(u32);
1292 }
1293
1294
1295 if (NULL == pmix_client_globals.myserver->info) {
1296 pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t);
1297 }
1298 if (NULL == pmix_client_globals.myserver->nptr) {
1299 pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_namespace_t);
1300 }
1301 pmix_ptl_base_recv_blocking(sd, (char*)nspace, PMIX_MAX_NSLEN+1);
1302 if (NULL != pmix_client_globals.myserver->nptr->nspace) {
1303 free(pmix_client_globals.myserver->nptr->nspace);
1304 }
1305 pmix_client_globals.myserver->nptr->nspace = strdup(nspace);
1306 if (NULL != pmix_client_globals.myserver->info->pname.nspace) {
1307 free(pmix_client_globals.myserver->info->pname.nspace);
1308 }
1309 pmix_client_globals.myserver->info->pname.nspace = strdup(nspace);
1310 pmix_ptl_base_recv_blocking(sd, (char*)&u32, sizeof(uint32_t));
1311 pmix_client_globals.myserver->info->pname.rank = htonl(u32);
1312
1313 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1314 "pmix: RECV CONNECT CONFIRMATION FOR TOOL %s:%d FROM SERVER %s:%d",
1315 pmix_globals.myid.nspace, pmix_globals.myid.rank,
1316 pmix_client_globals.myserver->info->pname.nspace,
1317 pmix_client_globals.myserver->info->pname.rank);
1318
1319
1320 pmix_ptl_base_recv_blocking(sd, (char*)&reply, sizeof(pmix_status_t));
1321 if (PMIX_SUCCESS != reply) {
1322
1323 if (PMIX_ERR_READY_FOR_HANDSHAKE == reply) {
1324 PMIX_PSEC_CLIENT_HANDSHAKE(reply, pmix_client_globals.myserver, sd);
1325 if (PMIX_SUCCESS != reply) {
1326 return reply;
1327 }
1328
1329 } else {
1330 return reply;
1331 }
1332 }
1333 }
1334
1335 if (sockopt) {
1336 if (0 != setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &save, sz)) {
1337 return PMIX_ERR_UNREACH;
1338 }
1339 }
1340
1341 return PMIX_SUCCESS;
1342 }
1343
1344 static pmix_status_t df_search(char *dirname, char *prefix,
1345 pmix_info_t info[], size_t ninfo,
1346 int *sd, char **nspace,
1347 pmix_rank_t *rank, char **uri)
1348 {
1349 char *suri, *nsp, *newdir;
1350 pmix_rank_t rk;
1351 pmix_status_t rc;
1352 struct stat buf;
1353 DIR *cur_dirp;
1354 struct dirent *dir_entry;
1355
1356 if (NULL == (cur_dirp = opendir(dirname))) {
1357 return PMIX_ERR_NOT_FOUND;
1358 }
1359
1360 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1361 "pmix:tcp: searching directory %s", dirname);
1362
1363
1364 while (NULL != (dir_entry = readdir(cur_dirp))) {
1365
1366 if (0 == strcmp(dir_entry->d_name, ".") ||
1367 0 == strcmp(dir_entry->d_name, "..")) {
1368 continue;
1369 }
1370 newdir = pmix_os_path(false, dirname, dir_entry->d_name, NULL);
1371 if (-1 == stat(newdir, &buf)) {
1372 free(newdir);
1373 continue;
1374 }
1375
1376 if (S_ISDIR(buf.st_mode)) {
1377 rc = df_search(newdir, prefix, info, ninfo, sd, nspace, rank, uri);
1378 free(newdir);
1379 if (PMIX_SUCCESS == rc) {
1380 closedir(cur_dirp);
1381 return rc;
1382 }
1383 continue;
1384 }
1385 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1386 "pmix:tcp: checking %s vs %s", dir_entry->d_name, prefix);
1387
1388 if (0 == strncmp(dir_entry->d_name, prefix, strlen(prefix))) {
1389
1390 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1391 "pmix:tcp: reading file %s", newdir);
1392 rc = parse_uri_file(newdir, &suri, &nsp, &rk);
1393 if (PMIX_SUCCESS == rc) {
1394
1395 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
1396 "pmix:tcp: attempting to connect to %s", suri);
1397 if (PMIX_SUCCESS == try_connect(suri, sd, info, ninfo)) {
1398 (*nspace) = nsp;
1399 *rank = rk;
1400 closedir(cur_dirp);
1401 *uri = suri;
1402 free(newdir);
1403 return PMIX_SUCCESS;
1404 }
1405 free(suri);
1406 free(nsp);
1407 }
1408 }
1409 free(newdir);
1410 }
1411 closedir(cur_dirp);
1412 return PMIX_ERR_NOT_FOUND;
1413 }