This source file includes following definitions.
- component_open
- component_close
- component_query
- setup_listener
- listener_cb
- connection_handler
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
27
28
29
30
31
32 #include <src/include/pmix_config.h>
33 #include <pmix_common.h>
34
35 #ifdef HAVE_FCNTL_H
36 #include <fcntl.h>
37 #endif
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41 #ifdef HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
43 #endif
44 #ifdef HAVE_SYS_UN_H
45 #include <sys/un.h>
46 #endif
47 #ifdef HAVE_SYS_UIO_H
48 #include <sys/uio.h>
49 #endif
50 #ifdef HAVE_SYS_TYPES_H
51 #include <sys/types.h>
52 #endif
53 #ifdef HAVE_SYS_STAT_H
54 #include <sys/stat.h>
55 #endif
56 #include <errno.h>
57
58 #include "src/util/argv.h"
59 #include "src/util/error.h"
60 #include "src/util/fd.h"
61 #include "src/util/show_help.h"
62 #include "src/util/strnlen.h"
63 #include "src/mca/bfrops/base/base.h"
64 #include "src/mca/gds/base/base.h"
65 #include "src/mca/psec/base/base.h"
66 #include "src/server/pmix_server_ops.h"
67
68 #include "src/mca/ptl/base/base.h"
69 #include "src/mca/ptl/usock/ptl_usock.h"
70
71 static pmix_status_t component_open(void);
72 static pmix_status_t component_close(void);
73 static int component_query(pmix_mca_base_module_t **module, int *priority);
74 static pmix_status_t setup_listener(pmix_info_t info[], size_t ninfo,
75 bool *need_listener);
76
77
78
79
80
81 PMIX_EXPORT pmix_ptl_usock_component_t mca_ptl_usock_component = {
82 .super = {
83 .base = {
84 PMIX_PTL_BASE_VERSION_1_0_0,
85
86
87 .pmix_mca_component_name = "usock",
88 PMIX_MCA_BASE_MAKE_VERSION(component,
89 PMIX_MAJOR_VERSION,
90 PMIX_MINOR_VERSION,
91 PMIX_RELEASE_VERSION),
92
93
94 .pmix_mca_open_component = component_open,
95 .pmix_mca_close_component = component_close,
96 .pmix_mca_query_component = component_query
97 },
98 .priority = 15,
99 .uri = NULL,
100 .setup_listener = setup_listener
101 },
102 .tmpdir = NULL,
103 .filename = NULL
104 };
105
106 static void connection_handler(int sd, short args, void *cbdata);
107 static void listener_cb(int incoming_sd, void *cbdata);
108
109 pmix_status_t component_open(void)
110 {
111 char *tdir;
112
113 memset(&mca_ptl_usock_component.connection, 0, sizeof(mca_ptl_usock_component.connection));
114
115
116
117 if (NULL == (tdir = getenv("PMIX_SYSTEM_TMPDIR"))) {
118 if (NULL == (tdir = getenv("TMPDIR"))) {
119 if (NULL == (tdir = getenv("TEMP"))) {
120 if (NULL == (tdir = getenv("TMP"))) {
121 tdir = "/tmp";
122 }
123 }
124 }
125 }
126 if (NULL != tdir) {
127 mca_ptl_usock_component.tmpdir = strdup(tdir);
128 }
129
130 return PMIX_SUCCESS;
131 }
132
133
134 pmix_status_t component_close(void)
135 {
136 if (NULL != mca_ptl_usock_component.tmpdir) {
137 free(mca_ptl_usock_component.tmpdir);
138 }
139 if (NULL != mca_ptl_usock_component.super.uri) {
140 free(mca_ptl_usock_component.super.uri);
141 }
142 if (NULL != mca_ptl_usock_component.filename) {
143
144 unlink(mca_ptl_usock_component.filename);
145 free(mca_ptl_usock_component.filename);
146 }
147
148 return PMIX_SUCCESS;
149 }
150
151 static int component_query(pmix_mca_base_module_t **module, int *priority)
152 {
153 *module = (pmix_mca_base_module_t*)&pmix_ptl_usock_module;
154 return PMIX_SUCCESS;
155 }
156
157
158
159
160
161
162
163
164
165
166 static pmix_status_t setup_listener(pmix_info_t info[], size_t ninfo,
167 bool *need_listener)
168 {
169 int flags;
170 size_t n;
171 pmix_listener_t *lt;
172 pmix_status_t rc;
173 socklen_t addrlen;
174 struct sockaddr_un *address;
175 bool disabled = false;
176 char *pmix_pid;
177 pid_t mypid;
178
179 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
180 "ptl:usock setup_listener");
181
182
183 if (!PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) {
184 return PMIX_ERR_NOT_SUPPORTED;
185 }
186
187
188 if (NULL != info) {
189 for (n=0; n < ninfo; n++) {
190 if (0 == strcmp(info[n].key, PMIX_USOCK_DISABLE)) {
191 disabled = PMIX_INFO_TRUE(&info[n]);;
192 break;
193 }
194 }
195 }
196
197
198 if (disabled) {
199 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
200 "ptl:usock not available");
201 return PMIX_ERR_NOT_AVAILABLE;
202 }
203
204 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
205 "ptl:usock setting up listener");
206
207 addrlen = sizeof(struct sockaddr_un);
208 address = (struct sockaddr_un*)&mca_ptl_usock_component.connection;
209 address->sun_family = AF_UNIX;
210
211
212 lt = PMIX_NEW(pmix_listener_t);
213
214
215
216 mypid = getpid();
217 if (0 > asprintf(&pmix_pid, "%s/pmix-%d", mca_ptl_usock_component.tmpdir, mypid)) {
218 PMIX_RELEASE(lt);
219 return PMIX_ERR_NOMEM;
220 }
221 if ((strlen(pmix_pid) + 1) > sizeof(address->sun_path)-1) {
222 pmix_show_help("help-pmix-server.txt", "rnd-path-too-long", true,
223 mca_ptl_usock_component.tmpdir, pmix_pid);
224 free(pmix_pid);
225 PMIX_RELEASE(lt);
226 return PMIX_ERR_INVALID_LENGTH;
227 }
228 snprintf(address->sun_path, sizeof(address->sun_path)-1, "%s", pmix_pid);
229 free(pmix_pid);
230
231 lt->varname = strdup("PMIX_SERVER_URI:PMIX_SERVER_URI2USOCK");
232 if (0 > asprintf(<->uri, "%s:%lu:%s", pmix_globals.myid.nspace,
233 (unsigned long)pmix_globals.myid.rank, address->sun_path)) {
234 PMIX_RELEASE(lt);
235 return PMIX_ERR_NOMEM;
236 }
237
238 mca_ptl_usock_component.filename = strdup(address->sun_path);
239
240 lt->protocol = PMIX_PROTOCOL_V1;
241 lt->ptl = (struct pmix_ptl_module_t*)&pmix_ptl_usock_module;
242 lt->cbfunc = connection_handler;
243 pmix_list_append(&pmix_ptl_globals.listeners, <->super);
244
245
246 lt->socket = socket(PF_UNIX, SOCK_STREAM, 0);
247 if (lt->socket < 0) {
248 printf("%s:%d socket() failed\n", __FILE__, __LINE__);
249 goto sockerror;
250 }
251
252
253 if (pmix_fd_set_cloexec(lt->socket) != PMIX_SUCCESS) {
254 CLOSE_THE_SOCKET(lt->socket);
255 goto sockerror;
256 }
257
258 if (bind(lt->socket, (struct sockaddr*)address, addrlen) < 0) {
259 printf("%s:%d bind() failed\n", __FILE__, __LINE__);
260 CLOSE_THE_SOCKET(lt->socket);
261 goto sockerror;
262 }
263
264 if (lt->owner_given) {
265 if (0 != chown(address->sun_path, lt->owner, -1)) {
266 pmix_output(0, "CANNOT CHOWN socket %s: %s", address->sun_path, strerror (errno));
267 CLOSE_THE_SOCKET(lt->socket);
268 goto sockerror;
269 }
270 }
271 if (lt->group_given) {
272 if (0 != chown(address->sun_path, -1, lt->group)) {
273 pmix_output(0, "CANNOT CHOWN socket %s: %s", address->sun_path, strerror (errno));
274 CLOSE_THE_SOCKET(lt->socket);
275 goto sockerror;
276 }
277 }
278
279 if (0 != chmod(address->sun_path, lt->mode)) {
280 pmix_output(0, "CANNOT CHMOD socket %s: %s", address->sun_path, strerror (errno));
281 CLOSE_THE_SOCKET(lt->socket);
282 goto sockerror;
283 }
284
285
286 if (listen(lt->socket, SOMAXCONN) < 0) {
287 printf("%s:%d listen() failed\n", __FILE__, __LINE__);
288 CLOSE_THE_SOCKET(lt->socket);
289 goto sockerror;
290 }
291
292
293 if ((flags = fcntl(lt->socket, F_GETFL, 0)) < 0) {
294 printf("%s:%d fcntl(F_GETFL) failed\n", __FILE__, __LINE__);
295 CLOSE_THE_SOCKET(lt->socket);
296 goto sockerror;
297 }
298 flags |= O_NONBLOCK;
299 if (fcntl(lt->socket, F_SETFL, flags) < 0) {
300 printf("%s:%d fcntl(F_SETFL) failed\n", __FILE__, __LINE__);
301 CLOSE_THE_SOCKET(lt->socket);
302 goto sockerror;
303 }
304
305
306 rc = PMIX_ERR_NOT_SUPPORTED;
307 if (NULL != pmix_host_server.listener) {
308 rc = pmix_host_server.listener(lt->socket, listener_cb, (void*)lt);
309 }
310
311 if (PMIX_SUCCESS != rc) {
312 *need_listener = true;
313 }
314
315 return PMIX_SUCCESS;
316
317 sockerror:
318 pmix_list_remove_item(&pmix_ptl_globals.listeners, <->super);
319 PMIX_RELEASE(lt);
320 return PMIX_ERROR;
321 }
322
323 static void listener_cb(int incoming_sd, void *cbdata)
324 {
325 pmix_pending_connection_t *pending_connection;
326
327
328 pmix_output_verbose(8, pmix_ptl_base_framework.framework_output,
329 "listen_cb: pushing new connection %d into evbase",
330 incoming_sd);
331 pending_connection = PMIX_NEW(pmix_pending_connection_t);
332 pending_connection->sd = incoming_sd;
333 pmix_event_assign(&pending_connection->ev, pmix_globals.evbase, -1,
334 EV_WRITE, connection_handler, pending_connection);
335 pmix_event_active(&pending_connection->ev, EV_WRITE, 1);
336 }
337
338 static void connection_handler(int sd, short args, void *cbdata)
339 {
340 pmix_pending_connection_t *pnd = (pmix_pending_connection_t*)cbdata;
341 char *msg, *ptr, *nspace, *version, *sec, *bfrops, *gds;
342 pmix_status_t rc;
343 unsigned int rank;
344 pmix_usock_hdr_t hdr;
345 pmix_namespace_t *nptr, *tmp;
346 pmix_rank_info_t *info;
347 pmix_peer_t *psave = NULL;
348 bool found;
349 pmix_proc_t proc;
350 size_t len;
351 pmix_bfrop_buffer_type_t bftype;
352 char **vers;
353 int major, minor, rel;
354 unsigned int msglen;
355 pmix_info_t ginfo;
356 pmix_byte_object_t cred;
357
358
359 PMIX_ACQUIRE_OBJECT(pnd);
360
361 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
362 "USOCK CONNECTION FROM PEER ON SOCKET %d", pnd->sd);
363
364
365 memset(&hdr, 0, sizeof(pmix_usock_hdr_t));
366
367
368 if (PMIX_SUCCESS != (rc = pmix_ptl_base_recv_blocking(pnd->sd, (char*)&hdr, sizeof(pmix_usock_hdr_t)))) {
369 CLOSE_THE_SOCKET(pnd->sd);
370 PMIX_RELEASE(pnd);
371 return;
372 }
373
374
375
376
377 if (PMIX_MAX_CRED_SIZE < hdr.nbytes) {
378 CLOSE_THE_SOCKET(pnd->sd);
379 PMIX_RELEASE(pnd);
380 return;
381 }
382 if (NULL == (msg = (char*)malloc(hdr.nbytes))) {
383 CLOSE_THE_SOCKET(pnd->sd);
384 PMIX_RELEASE(pnd);
385 return;
386 }
387 if (PMIX_SUCCESS != pmix_ptl_base_recv_blocking(pnd->sd, msg, hdr.nbytes)) {
388
389 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
390 "unable to complete recv of connect-ack with client ON SOCKET %d", pnd->sd);
391 free(msg);
392 CLOSE_THE_SOCKET(pnd->sd);
393 PMIX_RELEASE(pnd);
394 return;
395 }
396 len = hdr.nbytes;
397 ptr = msg;
398
399
400 PMIX_STRNLEN(msglen, ptr, len);
401 if (msglen < len) {
402 nspace = ptr;
403 ptr += strlen(nspace) + 1;
404 len -= strlen(nspace) + 1;
405 } else {
406 free(msg);
407 CLOSE_THE_SOCKET(pnd->sd);
408 PMIX_RELEASE(pnd);
409 return;
410 }
411
412
413 PMIX_STRNLEN(msglen, ptr, len);
414 if (msglen <= len) {
415 memcpy(&rank, ptr, sizeof(int));
416 ptr += sizeof(int);
417 len -= sizeof(int);
418 } else {
419 free(msg);
420 CLOSE_THE_SOCKET(pnd->sd);
421 PMIX_RELEASE(pnd);
422 return;
423 }
424
425
426 PMIX_STRNLEN(msglen, ptr, len);
427 if (msglen < len) {
428 version = ptr;
429 ptr += strlen(version) + 1;
430 len -= strlen(version) + 1;
431 } else {
432 free(msg);
433 CLOSE_THE_SOCKET(pnd->sd);
434 PMIX_RELEASE(pnd);
435 return;
436 }
437
438
439
440 vers = pmix_argv_split(version, '.');
441 major = strtol(vers[0], NULL, 10);
442 minor = strtol(vers[1], NULL, 10);
443 rel = strtol(vers[2], NULL, 10);
444 pmix_argv_free(vers);
445 if (1 == major && (2 != minor || 5 > rel)) {
446 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
447 "connection request from client of unsupported version %s", version);
448 free(msg);
449 CLOSE_THE_SOCKET(pnd->sd);
450 PMIX_RELEASE(pnd);
451 return;
452 }
453
454
455 if (1 == major) {
456
457 PMIX_STRNLEN(msglen, ptr, len);
458 if (msglen < len) {
459 cred.bytes = ptr;
460 cred.size = strlen(ptr);
461 ptr += cred.size + 1;
462 len -= cred.size + 1;
463 } else {
464 free(msg);
465 CLOSE_THE_SOCKET(pnd->sd);
466 PMIX_RELEASE(pnd);
467 return;
468 }
469 } else {
470
471 if (sizeof(size_t) < len) {
472 memcpy(&cred.size, ptr, sizeof(size_t));
473 ptr += sizeof(size_t);
474 len -= sizeof(size_t);
475 } else {
476 free(msg);
477 CLOSE_THE_SOCKET(pnd->sd);
478 PMIX_RELEASE(pnd);
479 return;
480 }
481 if (0 < cred.size) {
482 cred.bytes = ptr;
483 ptr += cred.size;
484 len -= cred.size;
485 } else {
486
487
488 cred.bytes = NULL;
489 }
490 }
491
492
493 PMIX_STRNLEN(msglen, ptr, len);
494 if (msglen < len) {
495 sec = ptr;
496 ptr += strlen(sec) + 1;
497 len -= strlen(sec) + 1;
498 } else {
499 free(msg);
500 CLOSE_THE_SOCKET(pnd->sd);
501 PMIX_RELEASE(pnd);
502 return;
503 }
504
505
506 PMIX_STRNLEN(msglen, ptr, len);
507 if (msglen < len) {
508 bfrops = ptr;
509 ptr += strlen(bfrops) + 1;
510 len -= strlen(bfrops) + 1;
511 } else {
512 free(msg);
513 CLOSE_THE_SOCKET(pnd->sd);
514 PMIX_RELEASE(pnd);
515 return;
516 }
517
518
519 if (0 < len) {
520 bftype = ptr[0];
521 ptr += 1;
522 len -= 1;
523 } else {
524 free(msg);
525 CLOSE_THE_SOCKET(pnd->sd);
526 PMIX_RELEASE(pnd);
527 return;
528 }
529
530
531 PMIX_STRNLEN(msglen, ptr, len);
532 if (msglen < len) {
533 gds = ptr;
534 ptr += strlen(gds) + 1;
535 len -= strlen(gds) + 1;
536 } else {
537 free(msg);
538 CLOSE_THE_SOCKET(pnd->sd);
539 PMIX_RELEASE(pnd);
540 return;
541 }
542
543 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
544 "connect-ack recvd from peer %s:%d:%s on socket %d",
545 nspace, rank, version, pnd->sd);
546
547
548 nptr = NULL;
549 PMIX_LIST_FOREACH(tmp, &pmix_server_globals.nspaces, pmix_namespace_t) {
550 if (0 == strcmp(tmp->nspace, nspace)) {
551 nptr = tmp;
552 break;
553 }
554 }
555 if (NULL == nptr) {
556
557 free(msg);
558
559 rc = PMIX_ERR_NOT_FOUND;
560 goto error;
561 }
562
563
564 info = NULL;
565 found = false;
566 PMIX_LIST_FOREACH(info, &nptr->ranks, pmix_rank_info_t) {
567 if (info->pname.rank == rank) {
568 found = true;
569 break;
570 }
571 }
572 if (!found) {
573
574 free(msg);
575
576 rc = PMIX_ERR_NOT_FOUND;
577 goto error;
578 }
579
580
581
582 psave = PMIX_NEW(pmix_peer_t);
583 if (NULL == psave) {
584 free(msg);
585 rc = PMIX_ERR_NOMEM;
586 goto error;
587 }
588
589 if (1 == major) {
590 psave->proc_type = PMIX_PROC_CLIENT | PMIX_PROC_V1;
591 } else if (2 == major && 0 == minor) {
592 psave->proc_type = PMIX_PROC_CLIENT | PMIX_PROC_V20;
593 } else if (2 == major && 1 == minor) {
594 psave->proc_type = PMIX_PROC_CLIENT | PMIX_PROC_V21;
595 } else if (3 == major) {
596 psave->proc_type = PMIX_PROC_CLIENT | PMIX_PROC_V3;
597 } else {
598
599 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
600 "connection request from client of unrecognized version %s", version);
601 free(msg);
602 PMIX_RELEASE(psave);
603 CLOSE_THE_SOCKET(pnd->sd);
604 PMIX_RELEASE(pnd);
605 return;
606 }
607
608 psave->protocol = pnd->protocol;
609
610 PMIX_RETAIN(nptr);
611 psave->nptr = nptr;
612 PMIX_RETAIN(info);
613 psave->info = info;
614
615 psave->epilog.uid = info->uid;
616 psave->epilog.gid = info->gid;
617 nptr->epilog.uid = info->uid;
618 nptr->epilog.gid = info->gid;
619 info->proc_cnt++;
620 psave->sd = pnd->sd;
621 if (0 > (psave->index = pmix_pointer_array_add(&pmix_server_globals.clients, psave))) {
622 free(msg);
623 info->proc_cnt--;
624 PMIX_RELEASE(info);
625 PMIX_RELEASE(psave);
626
627 CLOSE_THE_SOCKET(pnd->sd);
628 PMIX_RELEASE(pnd);
629 return;
630 }
631 info->peerid = psave->index;
632
633
634 nptr->compat.psec = pmix_psec_base_assign_module(sec);
635 if (NULL == nptr->compat.psec) {
636 free(msg);
637 info->proc_cnt--;
638 PMIX_RELEASE(info);
639 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
640 PMIX_RELEASE(psave);
641
642 goto error;
643 }
644
645
646 nptr->compat.bfrops = pmix_bfrops_base_assign_module(bfrops);
647 if (NULL == nptr->compat.bfrops) {
648 free(msg);
649 info->proc_cnt--;
650 PMIX_RELEASE(info);
651 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
652 PMIX_RELEASE(psave);
653
654 goto error;
655 }
656
657 nptr->compat.type = bftype;
658
659
660 if (NULL != gds) {
661 PMIX_INFO_LOAD(&ginfo, PMIX_GDS_MODULE, gds, PMIX_STRING);
662 nptr->compat.gds = pmix_gds_base_assign_module(&ginfo, 1);
663 PMIX_INFO_DESTRUCT(&ginfo);
664 } else {
665 nptr->compat.gds = pmix_gds_base_assign_module(NULL, 0);
666 }
667 if (NULL == nptr->compat.gds) {
668 free(msg);
669 info->proc_cnt--;
670 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
671 PMIX_RELEASE(psave);
672
673 goto error;
674 }
675
676
677
678 if (!nptr->version_stored) {
679 PMIX_INFO_LOAD(&ginfo, PMIX_BFROPS_MODULE, nptr->compat.bfrops->version, PMIX_STRING);
680 PMIX_GDS_CACHE_JOB_INFO(rc, pmix_globals.mypeer, nptr, &ginfo, 1);
681 PMIX_INFO_DESTRUCT(&ginfo);
682 nptr->version_stored = true;
683 }
684
685
686
687
688 nptr->compat.ptl = &pmix_ptl_usock_module;
689
690
691 PMIX_PSEC_VALIDATE_CONNECTION(rc, psave, NULL, 0, NULL, 0, &cred);
692
693 free(msg);
694
695 if (PMIX_SUCCESS != rc) {
696 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
697 "validation of client credentials failed: %s",
698 PMIx_Error_string(rc));
699 info->proc_cnt--;
700 PMIX_RELEASE(info);
701 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
702 PMIX_RELEASE(psave);
703
704 CLOSE_THE_SOCKET(pnd->sd);
705 PMIX_RELEASE(pnd);
706 return;
707 }
708
709
710 if (PMIX_SUCCESS != (rc = pmix_ptl_base_send_blocking(pnd->sd, (char*)&psave->index, sizeof(int)))) {
711 PMIX_ERROR_LOG(rc);
712 info->proc_cnt--;
713 PMIX_RELEASE(info);
714 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
715 PMIX_RELEASE(psave);
716 CLOSE_THE_SOCKET(pnd->sd);
717 PMIX_RELEASE(pnd);
718 return;
719 }
720
721 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
722 "connect-ack from client completed");
723
724
725 if (NULL != pmix_host_server.client_connected) {
726 pmix_strncpy(proc.nspace, psave->info->pname.nspace, PMIX_MAX_NSLEN);
727 proc.rank = psave->info->pname.rank;
728 rc = pmix_host_server.client_connected(&proc, psave->info->server_object, NULL, NULL);
729 if (PMIX_SUCCESS != rc && PMIX_OPERATION_SUCCEEDED != rc) {
730 PMIX_ERROR_LOG(rc);
731 info->proc_cnt--;
732 PMIX_RELEASE(info);
733 pmix_pointer_array_set_item(&pmix_server_globals.clients, psave->index, NULL);
734 PMIX_RELEASE(psave);
735 CLOSE_THE_SOCKET(pnd->sd);
736 }
737 }
738
739
740 pmix_event_assign(&psave->recv_event, pmix_globals.evbase, pnd->sd,
741 EV_READ|EV_PERSIST, pmix_usock_recv_handler, psave);
742 pmix_event_add(&psave->recv_event, NULL);
743 psave->recv_ev_active = true;
744 pmix_event_assign(&psave->send_event, pmix_globals.evbase, pnd->sd,
745 EV_WRITE|EV_PERSIST, pmix_usock_send_handler, psave);
746 pmix_output_verbose(2, pmix_ptl_base_framework.framework_output,
747 "pmix:server client %s:%u has connected on socket %d",
748 psave->info->pname.nspace, psave->info->pname.rank, psave->sd);
749
750 PMIX_RELEASE(pnd);
751 return;
752
753 error:
754
755 if (PMIX_SUCCESS != pmix_ptl_base_send_blocking(pnd->sd, (char*)&rc, sizeof(int))) {
756 PMIX_ERROR_LOG(rc);
757 }
758 CLOSE_THE_SOCKET(pnd->sd);
759 PMIX_RELEASE(pnd);
760 return;
761 }