2 A server based on unix domain socket
4 Copyright (C) Amitay Isaacs 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
28 #include "lib/async_req/async_sock.h"
29 #include "lib/util/debug.h"
30 #include "lib/util/blocking.h"
31 #include "lib/util/dlinklist.h"
32 #include "lib/util/tevent_unix.h"
33 #include "lib/util/become_daemon.h"
34 #include "lib/util/sys_rw.h"
36 #include "common/logging.h"
37 #include "common/reqid.h"
38 #include "common/comm.h"
39 #include "common/pidfile.h"
40 #include "common/system.h"
41 #include "common/sock_daemon.h"
44 struct sock_socket
*prev
, *next
;
47 struct sock_socket_funcs
*funcs
;
51 struct tevent_req
*req
;
55 struct sock_client
*prev
, *next
;
57 struct tevent_req
*req
;
58 struct sock_client_context
*client_ctx
;
61 struct sock_client_context
{
62 struct tevent_context
*ev
;
63 struct sock_socket
*sock
;
65 struct comm_context
*comm
;
67 struct sock_client
*client
;
70 struct sock_daemon_context
{
71 struct sock_daemon_funcs
*funcs
;
74 struct pidfile_context
*pid_ctx
;
75 struct sock_socket
*socket_list
;
80 * Process a single client
83 static void sock_client_read_handler(uint8_t *buf
, size_t buflen
,
85 static void sock_client_read_done(struct tevent_req
*subreq
);
86 static void sock_client_dead_handler(void *private_data
);
87 static int sock_client_context_destructor(
88 struct sock_client_context
*client_ctx
);
90 static int sock_client_context_init(TALLOC_CTX
*mem_ctx
,
91 struct tevent_context
*ev
,
92 struct sock_socket
*sock
,
94 struct sock_client
*client
,
95 struct sock_client_context
**result
)
97 struct sock_client_context
*client_ctx
;
100 client_ctx
= talloc_zero(mem_ctx
, struct sock_client_context
);
101 if (client_ctx
== NULL
) {
106 client_ctx
->sock
= sock
;
107 client_ctx
->fd
= client_fd
;
108 client_ctx
->client
= client
;
110 ret
= comm_setup(client_ctx
, ev
, client_fd
,
111 sock_client_read_handler
, client_ctx
,
112 sock_client_dead_handler
, client_ctx
,
115 talloc_free(client_ctx
);
119 if (sock
->funcs
->connect
!= NULL
) {
123 (void) ctdb_get_peer_pid(client_fd
, &pid
);
125 status
= sock
->funcs
->connect(client_ctx
,
129 talloc_free(client_ctx
);
135 talloc_set_destructor(client_ctx
, sock_client_context_destructor
);
137 *result
= client_ctx
;
141 static void sock_client_read_handler(uint8_t *buf
, size_t buflen
,
144 struct sock_client_context
*client_ctx
= talloc_get_type_abort(
145 private_data
, struct sock_client_context
);
146 struct sock_socket
*sock
= client_ctx
->sock
;
147 struct tevent_req
*subreq
;
149 subreq
= sock
->funcs
->read_send(client_ctx
, client_ctx
->ev
,
150 client_ctx
, buf
, buflen
,
152 if (subreq
== NULL
) {
153 talloc_free(client_ctx
);
156 tevent_req_set_callback(subreq
, sock_client_read_done
, client_ctx
);
159 static void sock_client_read_done(struct tevent_req
*subreq
)
161 struct sock_client_context
*client_ctx
= tevent_req_callback_data(
162 subreq
, struct sock_client_context
);
163 struct sock_socket
*sock
= client_ctx
->sock
;
167 status
= sock
->funcs
->read_recv(subreq
, &ret
);
169 D_ERR("client read failed with ret=%d\n", ret
);
170 talloc_free(client_ctx
);
174 static void sock_client_dead_handler(void *private_data
)
176 struct sock_client_context
*client_ctx
= talloc_get_type_abort(
177 private_data
, struct sock_client_context
);
178 struct sock_socket
*sock
= client_ctx
->sock
;
180 if (sock
->funcs
->disconnect
!= NULL
) {
181 sock
->funcs
->disconnect(client_ctx
, sock
->private_data
);
184 talloc_free(client_ctx
);
187 static int sock_client_context_destructor(
188 struct sock_client_context
*client_ctx
)
190 TALLOC_FREE(client_ctx
->client
);
191 TALLOC_FREE(client_ctx
->comm
);
192 if (client_ctx
->fd
!= -1) {
193 close(client_ctx
->fd
);
201 * Process a single listening socket
204 static int socket_setup(const char *sockpath
, bool remove_before_use
)
206 struct sockaddr_un addr
;
210 memset(&addr
, 0, sizeof(addr
));
211 addr
.sun_family
= AF_UNIX
;
213 len
= strlcpy(addr
.sun_path
, sockpath
, sizeof(addr
.sun_path
));
214 if (len
>= sizeof(addr
.sun_path
)) {
215 D_ERR("socket path too long: %s\n", sockpath
);
219 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
221 D_ERR("socket create failed - %s\n", sockpath
);
225 ret
= set_blocking(fd
, false);
227 D_ERR("socket set nonblocking failed - %s\n", sockpath
);
232 if (remove_before_use
) {
236 ret
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
238 D_ERR("socket bind failed - %s\n", sockpath
);
243 ret
= listen(fd
, 10);
245 D_ERR("socket listen failed - %s\n", sockpath
);
250 D_NOTICE("listening on %s\n", sockpath
);
255 static int sock_socket_destructor(struct sock_socket
*sock
);
257 static int sock_socket_init(TALLOC_CTX
*mem_ctx
, const char *sockpath
,
258 struct sock_socket_funcs
*funcs
,
260 struct sock_socket
**result
)
262 struct sock_socket
*sock
;
267 if (funcs
->read_send
== NULL
|| funcs
->read_recv
== NULL
) {
271 sock
= talloc_zero(mem_ctx
, struct sock_socket
);
276 sock
->sockpath
= talloc_strdup(sock
, sockpath
);
277 if (sock
->sockpath
== NULL
) {
282 sock
->private_data
= private_data
;
285 talloc_set_destructor(sock
, sock_socket_destructor
);
291 static int sock_socket_destructor(struct sock_socket
*sock
)
293 TALLOC_FREE(sock
->req
);
295 if (sock
->fd
!= -1) {
300 unlink(sock
->sockpath
);
305 struct sock_socket_start_state
{
306 struct tevent_context
*ev
;
307 struct sock_socket
*sock
;
309 struct sock_client
*client_list
;
312 static int sock_socket_start_state_destructor(
313 struct sock_socket_start_state
*state
);
314 static void sock_socket_start_new_client(struct tevent_req
*subreq
);
315 static int sock_socket_start_client_destructor(struct sock_client
*client
);
317 static struct tevent_req
*sock_socket_start_send(TALLOC_CTX
*mem_ctx
,
318 struct tevent_context
*ev
,
319 struct sock_socket
*sock
,
320 bool remove_before_use
)
322 struct tevent_req
*req
, *subreq
;
323 struct sock_socket_start_state
*state
;
325 req
= tevent_req_create(mem_ctx
, &state
,
326 struct sock_socket_start_state
);
334 sock
->fd
= socket_setup(sock
->sockpath
, remove_before_use
);
335 if (sock
->fd
== -1) {
336 tevent_req_error(req
, EIO
);
337 return tevent_req_post(req
, ev
);
340 talloc_set_destructor(state
, sock_socket_start_state_destructor
);
342 subreq
= accept_send(state
, ev
, sock
->fd
);
343 if (tevent_req_nomem(subreq
, req
)) {
344 return tevent_req_post(req
, ev
);
346 tevent_req_set_callback(subreq
, sock_socket_start_new_client
, req
);
353 static int sock_socket_start_state_destructor(
354 struct sock_socket_start_state
*state
)
356 struct sock_client
*client
;
358 while ((client
= state
->client_list
) != NULL
) {
365 static void sock_socket_start_new_client(struct tevent_req
*subreq
)
367 struct tevent_req
*req
= tevent_req_callback_data(
368 subreq
, struct tevent_req
);
369 struct sock_socket_start_state
*state
= tevent_req_data(
370 req
, struct sock_socket_start_state
);
371 struct sock_client
*client
;
374 client_fd
= accept_recv(subreq
, NULL
, NULL
, &ret
);
376 if (client_fd
== -1) {
377 D_ERR("failed to accept new connection\n");
380 subreq
= accept_send(state
, state
->ev
, state
->sock
->fd
);
381 if (tevent_req_nomem(subreq
, req
)) {
384 tevent_req_set_callback(subreq
, sock_socket_start_new_client
, req
);
386 if (client_fd
== -1) {
390 client
= talloc_zero(state
, struct sock_client
);
391 if (tevent_req_nomem(client
, req
)) {
398 ret
= sock_client_context_init(client
, state
->ev
, state
->sock
,
399 client_fd
, client
, &client
->client_ctx
);
405 talloc_set_destructor(client
, sock_socket_start_client_destructor
);
406 DLIST_ADD(state
->client_list
, client
);
409 static int sock_socket_start_client_destructor(struct sock_client
*client
)
411 struct sock_socket_start_state
*state
= tevent_req_data(
412 client
->req
, struct sock_socket_start_state
);
414 DLIST_REMOVE(state
->client_list
, client
);
415 TALLOC_FREE(client
->client_ctx
);
420 static bool sock_socket_start_recv(struct tevent_req
*req
, int *perr
,
421 TALLOC_CTX
*mem_ctx
, const char **sockpath
)
423 struct sock_socket_start_state
*state
= tevent_req_data(
424 req
, struct sock_socket_start_state
);
427 state
->sock
->req
= NULL
;
429 if (tevent_req_is_unix_error(req
, &ret
)) {
436 if (sockpath
!= NULL
) {
437 *sockpath
= talloc_steal(mem_ctx
, state
->sock
->sockpath
);
444 * Send message to a client
447 struct tevent_req
*sock_socket_write_send(TALLOC_CTX
*mem_ctx
,
448 struct tevent_context
*ev
,
449 struct sock_client_context
*client_ctx
,
450 uint8_t *buf
, size_t buflen
)
452 struct tevent_req
*req
;
454 req
= comm_write_send(mem_ctx
, ev
, client_ctx
->comm
, buf
, buflen
);
459 bool sock_socket_write_recv(struct tevent_req
*req
, int *perr
)
464 status
= comm_write_recv(req
, &ret
);
478 int sock_daemon_setup(TALLOC_CTX
*mem_ctx
, const char *daemon_name
,
479 const char *logging
, const char *debug_level
,
480 struct sock_daemon_funcs
*funcs
,
482 struct sock_daemon_context
**out
)
484 struct sock_daemon_context
*sockd
;
487 sockd
= talloc_zero(mem_ctx
, struct sock_daemon_context
);
492 sockd
->funcs
= funcs
;
493 sockd
->private_data
= private_data
;
494 sockd
->startup_fd
= -1;
496 ret
= logging_init(sockd
, logging
, debug_level
, daemon_name
);
499 "Failed to initialize logging, logging=%s, debug=%s\n",
500 logging
, debug_level
);
508 int sock_daemon_add_unix(struct sock_daemon_context
*sockd
,
509 const char *sockpath
,
510 struct sock_socket_funcs
*funcs
,
513 struct sock_socket
*sock
;
516 ret
= sock_socket_init(sockd
, sockpath
, funcs
, private_data
, &sock
);
522 DLIST_ADD(sockd
->socket_list
, sock
);
526 bool sock_daemon_set_startup_fd(struct sock_daemon_context
*sockd
, int fd
)
528 if (! set_close_on_exec(fd
)) {
529 D_ERR("Failed to set close-on-exec on startup fd\n");
533 sockd
->startup_fd
= fd
;
541 struct sock_daemon_run_state
{
542 struct tevent_context
*ev
;
543 struct sock_daemon_context
*sockd
;
550 static void sock_daemon_run_started(struct tevent_req
*subreq
);
551 static void sock_daemon_run_startup_done(struct tevent_req
*subreq
);
552 static void sock_daemon_run_signal_handler(struct tevent_context
*ev
,
553 struct tevent_signal
*se
,
554 int signum
, int count
, void *siginfo
,
556 static void sock_daemon_run_reconfigure(struct tevent_req
*req
);
557 static void sock_daemon_run_reconfigure_done(struct tevent_req
*subreq
);
558 static void sock_daemon_run_shutdown(struct tevent_req
*req
);
559 static void sock_daemon_run_shutdown_done(struct tevent_req
*subreq
);
560 static void sock_daemon_run_exit(struct tevent_req
*req
);
561 static bool sock_daemon_run_socket_listen(struct tevent_req
*req
);
562 static void sock_daemon_run_socket_fail(struct tevent_req
*subreq
);
563 static void sock_daemon_run_watch_pid(struct tevent_req
*subreq
);
564 static void sock_daemon_run_wait(struct tevent_req
*req
);
565 static void sock_daemon_run_wait_done(struct tevent_req
*subreq
);
566 static void sock_daemon_startup_notify(struct sock_daemon_context
*sockd
);
568 struct tevent_req
*sock_daemon_run_send(TALLOC_CTX
*mem_ctx
,
569 struct tevent_context
*ev
,
570 struct sock_daemon_context
*sockd
,
572 bool do_fork
, bool create_session
,
575 struct tevent_req
*req
, *subreq
;
576 struct sock_daemon_run_state
*state
;
577 struct tevent_signal
*se
;
579 req
= tevent_req_create(mem_ctx
, &state
,
580 struct sock_daemon_run_state
);
585 become_daemon(do_fork
, !create_session
, false);
587 if (pidfile
!= NULL
) {
588 int ret
= pidfile_context_create(sockd
, pidfile
,
591 tevent_req_error(req
, EEXIST
);
592 return tevent_req_post(req
, ev
);
597 state
->sockd
= sockd
;
598 state
->pid_watch
= pid_watch
;
601 subreq
= tevent_wakeup_send(state
, ev
,
602 tevent_timeval_current_ofs(0, 0));
603 if (tevent_req_nomem(subreq
, req
)) {
604 return tevent_req_post(req
, ev
);
606 tevent_req_set_callback(subreq
, sock_daemon_run_started
, req
);
608 se
= tevent_add_signal(ev
, state
, SIGHUP
, 0,
609 sock_daemon_run_signal_handler
, req
);
610 if (tevent_req_nomem(se
, req
)) {
611 return tevent_req_post(req
, ev
);
614 se
= tevent_add_signal(ev
, state
, SIGUSR1
, 0,
615 sock_daemon_run_signal_handler
, req
);
616 if (tevent_req_nomem(se
, req
)) {
617 return tevent_req_post(req
, ev
);
620 se
= tevent_add_signal(ev
, state
, SIGINT
, 0,
621 sock_daemon_run_signal_handler
, req
);
622 if (tevent_req_nomem(se
, req
)) {
623 return tevent_req_post(req
, ev
);
626 se
= tevent_add_signal(ev
, state
, SIGTERM
, 0,
627 sock_daemon_run_signal_handler
, req
);
628 if (tevent_req_nomem(se
, req
)) {
629 return tevent_req_post(req
, ev
);
633 subreq
= tevent_wakeup_send(state
, ev
,
634 tevent_timeval_current_ofs(1,0));
635 if (tevent_req_nomem(subreq
, req
)) {
636 return tevent_req_post(req
, ev
);
638 tevent_req_set_callback(subreq
, sock_daemon_run_watch_pid
,
645 static void sock_daemon_run_started(struct tevent_req
*subreq
)
647 struct tevent_req
*req
= tevent_req_callback_data(
648 subreq
, struct tevent_req
);
649 struct sock_daemon_run_state
*state
= tevent_req_data(
650 req
, struct sock_daemon_run_state
);
651 struct sock_daemon_context
*sockd
= state
->sockd
;
654 status
= tevent_wakeup_recv(subreq
);
657 tevent_req_error(req
, EIO
);
661 D_NOTICE("daemon started, pid=%u\n", getpid());
663 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->startup_send
!= NULL
&&
664 sockd
->funcs
->startup_recv
!= NULL
) {
665 subreq
= sockd
->funcs
->startup_send(state
, state
->ev
,
666 sockd
->private_data
);
667 if (tevent_req_nomem(subreq
, req
)) {
670 tevent_req_set_callback(subreq
, sock_daemon_run_startup_done
,
675 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->startup
!= NULL
) {
678 ret
= sockd
->funcs
->startup(sockd
->private_data
);
680 D_ERR("startup failed, ret=%d\n", ret
);
681 tevent_req_error(req
, EIO
);
685 D_NOTICE("startup completed successfully\n");
688 status
= sock_daemon_run_socket_listen(req
);
692 sock_daemon_run_wait(req
);
694 sock_daemon_startup_notify(sockd
);
697 static void sock_daemon_run_startup_done(struct tevent_req
*subreq
)
699 struct tevent_req
*req
= tevent_req_callback_data(
700 subreq
, struct tevent_req
);
701 struct sock_daemon_run_state
*state
= tevent_req_data(
702 req
, struct sock_daemon_run_state
);
703 struct sock_daemon_context
*sockd
= state
->sockd
;
707 status
= sockd
->funcs
->startup_recv(subreq
, &ret
);
710 D_ERR("startup failed, ret=%d\n", ret
);
711 tevent_req_error(req
, EIO
);
715 D_NOTICE("startup completed successfully\n");
717 status
= sock_daemon_run_socket_listen(req
);
721 sock_daemon_run_wait(req
);
723 sock_daemon_startup_notify(sockd
);
726 static void sock_daemon_run_signal_handler(struct tevent_context
*ev
,
727 struct tevent_signal
*se
,
728 int signum
, int count
, void *siginfo
,
731 struct tevent_req
*req
= talloc_get_type_abort(
732 private_data
, struct tevent_req
);
733 struct sock_daemon_run_state
*state
= tevent_req_data(
734 req
, struct sock_daemon_run_state
);
736 D_NOTICE("Received signal %d\n", signum
);
738 if (signum
== SIGHUP
|| signum
== SIGUSR1
) {
739 sock_daemon_run_reconfigure(req
);
743 if (signum
== SIGINT
|| signum
== SIGTERM
) {
744 state
->exit_code
= EINTR
;
745 sock_daemon_run_shutdown(req
);
749 static void sock_daemon_run_reconfigure(struct tevent_req
*req
)
751 struct tevent_req
*subreq
;
752 struct sock_daemon_run_state
*state
= tevent_req_data(
753 req
, struct sock_daemon_run_state
);
754 struct sock_daemon_context
*sockd
= state
->sockd
;
756 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->reconfigure_send
!= NULL
&&
757 sockd
->funcs
->reconfigure_recv
!= NULL
) {
758 subreq
= sockd
->funcs
->reconfigure_send(state
, state
->ev
,
759 sockd
->private_data
);
760 if (tevent_req_nomem(subreq
, req
)) {
763 tevent_req_set_callback(subreq
,
764 sock_daemon_run_reconfigure_done
, req
);
768 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->reconfigure
!= NULL
) {
771 ret
= sockd
->funcs
->reconfigure(sockd
->private_data
);
773 D_ERR("reconfigure failed, ret=%d\n", ret
);
777 D_NOTICE("reconfigure completed successfully\n");
781 static void sock_daemon_run_reconfigure_done(struct tevent_req
*subreq
)
783 struct tevent_req
*req
= tevent_req_callback_data(
784 subreq
, struct tevent_req
);
785 struct sock_daemon_run_state
*state
= tevent_req_data(
786 req
, struct sock_daemon_run_state
);
787 struct sock_daemon_context
*sockd
= state
->sockd
;
791 status
= sockd
->funcs
->reconfigure_recv(subreq
, &ret
);
794 D_ERR("reconfigure failed, ret=%d\n", ret
);
798 D_NOTICE("reconfigure completed successfully\n");
801 static void sock_daemon_run_shutdown(struct tevent_req
*req
)
803 struct tevent_req
*subreq
;
804 struct sock_daemon_run_state
*state
= tevent_req_data(
805 req
, struct sock_daemon_run_state
);
806 struct sock_daemon_context
*sockd
= state
->sockd
;
807 struct sock_socket
*sock
;
809 D_NOTICE("Shutting down\n");
811 while ((sock
= sockd
->socket_list
) != NULL
) {
812 DLIST_REMOVE(sockd
->socket_list
, sock
);
816 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->shutdown_send
!= NULL
&&
817 sockd
->funcs
->shutdown_recv
!= NULL
) {
818 subreq
= sockd
->funcs
->shutdown_send(state
, state
->ev
,
819 sockd
->private_data
);
820 if (subreq
== NULL
) {
821 sock_daemon_run_exit(req
);
824 tevent_req_set_callback(subreq
, sock_daemon_run_shutdown_done
,
829 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->shutdown
!= NULL
) {
830 sockd
->funcs
->shutdown(sockd
->private_data
);
833 sock_daemon_run_exit(req
);
836 static void sock_daemon_run_shutdown_done(struct tevent_req
*subreq
)
838 struct tevent_req
*req
= tevent_req_callback_data(
839 subreq
, struct tevent_req
);
840 struct sock_daemon_run_state
*state
= tevent_req_data(
841 req
, struct sock_daemon_run_state
);
842 struct sock_daemon_context
*sockd
= state
->sockd
;
844 sockd
->funcs
->shutdown_recv(subreq
);
847 sock_daemon_run_exit(req
);
850 static void sock_daemon_run_exit(struct tevent_req
*req
)
852 struct sock_daemon_run_state
*state
= tevent_req_data(
853 req
, struct sock_daemon_run_state
);
854 struct sock_daemon_context
*sockd
= state
->sockd
;
856 TALLOC_FREE(sockd
->pid_ctx
);
858 if (state
->exit_code
== 0) {
859 tevent_req_done(req
);
861 tevent_req_error(req
, state
->exit_code
);
865 static bool sock_daemon_run_socket_listen(struct tevent_req
*req
)
867 struct tevent_req
*subreq
;
868 struct sock_daemon_run_state
*state
= tevent_req_data(
869 req
, struct sock_daemon_run_state
);
870 struct sock_daemon_context
*sockd
= state
->sockd
;
871 struct sock_socket
*sock
;
872 bool remove_before_use
= false;
874 if (sockd
->pid_ctx
!= NULL
) {
875 remove_before_use
= true;
877 for (sock
= sockd
->socket_list
; sock
!= NULL
; sock
= sock
->next
) {
878 subreq
= sock_socket_start_send(state
, state
->ev
, sock
,
880 if (tevent_req_nomem(subreq
, req
)) {
883 tevent_req_set_callback(subreq
, sock_daemon_run_socket_fail
,
890 static void sock_daemon_run_socket_fail(struct tevent_req
*subreq
)
892 struct tevent_req
*req
= tevent_req_callback_data(
893 subreq
, struct tevent_req
);
894 struct sock_daemon_run_state
*state
= tevent_req_data(
895 req
, struct sock_daemon_run_state
);
896 const char *sockpath
= NULL
;
900 status
= sock_socket_start_recv(subreq
, &ret
, state
, &sockpath
);
903 D_ERR("socket %s closed unexpectedly\n", sockpath
);
904 state
->exit_code
= ret
;
906 state
->exit_code
= 0;
909 sock_daemon_run_shutdown(req
);
912 static void sock_daemon_run_watch_pid(struct tevent_req
*subreq
)
914 struct tevent_req
*req
= tevent_req_callback_data(
915 subreq
, struct tevent_req
);
916 struct sock_daemon_run_state
*state
= tevent_req_data(
917 req
, struct sock_daemon_run_state
);
921 status
= tevent_wakeup_recv(subreq
);
924 tevent_req_error(req
, EIO
);
928 ret
= kill(state
->pid_watch
, 0);
930 if (errno
== ESRCH
) {
931 D_ERR("PID %d gone away, exiting\n", state
->pid_watch
);
932 state
->exit_code
= ESRCH
;
933 sock_daemon_run_shutdown(req
);
936 D_ERR("Failed to check PID status %d, ret=%d\n",
937 state
->pid_watch
, errno
);
941 subreq
= tevent_wakeup_send(state
, state
->ev
,
942 tevent_timeval_current_ofs(5,0));
943 if (tevent_req_nomem(subreq
, req
)) {
946 tevent_req_set_callback(subreq
, sock_daemon_run_watch_pid
, req
);
949 static void sock_daemon_run_wait(struct tevent_req
*req
)
951 struct tevent_req
*subreq
;
952 struct sock_daemon_run_state
*state
= tevent_req_data(
953 req
, struct sock_daemon_run_state
);
954 struct sock_daemon_context
*sockd
= state
->sockd
;
956 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->wait_send
!= NULL
&&
957 sockd
->funcs
->wait_recv
!= NULL
) {
958 subreq
= sockd
->funcs
->wait_send(state
, state
->ev
,
959 sockd
->private_data
);
960 if (tevent_req_nomem(subreq
, req
)) {
963 tevent_req_set_callback(subreq
, sock_daemon_run_wait_done
,
968 static void sock_daemon_run_wait_done(struct tevent_req
*subreq
)
970 struct tevent_req
*req
= tevent_req_callback_data(
971 subreq
, struct tevent_req
);
972 struct sock_daemon_run_state
*state
= tevent_req_data(
973 req
, struct sock_daemon_run_state
);
974 struct sock_daemon_context
*sockd
= state
->sockd
;
978 status
= sockd
->funcs
->wait_recv(subreq
, &ret
);
981 state
->exit_code
= ret
;
983 state
->exit_code
= 0;
986 sock_daemon_run_shutdown(req
);
989 static void sock_daemon_startup_notify(struct sock_daemon_context
*sockd
)
991 if (sockd
->startup_fd
!= -1) {
992 unsigned int zero
= 0;
995 num
= sys_write(sockd
->startup_fd
, &zero
, sizeof(zero
));
996 if (num
!= sizeof(zero
)) {
997 D_WARNING("Failed to write zero to pipe FD\n");
1002 bool sock_daemon_run_recv(struct tevent_req
*req
, int *perr
)
1006 if (tevent_req_is_unix_error(req
, &ret
)) {
1016 int sock_daemon_run(struct tevent_context
*ev
,
1017 struct sock_daemon_context
*sockd
,
1018 const char *pidfile
,
1019 bool do_fork
, bool create_session
,
1022 struct tevent_req
*req
;
1026 req
= sock_daemon_run_send(ev
, ev
, sockd
,
1027 pidfile
, do_fork
, create_session
, pid_watch
);
1032 tevent_req_poll(req
, ev
);
1034 status
= sock_daemon_run_recv(req
, &ret
);