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 void sock_daemon_set_startup_fd(struct sock_daemon_context
*sockd
, int fd
)
528 sockd
->startup_fd
= fd
;
535 struct sock_daemon_run_state
{
536 struct tevent_context
*ev
;
537 struct sock_daemon_context
*sockd
;
544 static void sock_daemon_run_started(struct tevent_req
*subreq
);
545 static void sock_daemon_run_startup_done(struct tevent_req
*subreq
);
546 static void sock_daemon_run_signal_handler(struct tevent_context
*ev
,
547 struct tevent_signal
*se
,
548 int signum
, int count
, void *siginfo
,
550 static void sock_daemon_run_reconfigure(struct tevent_req
*req
);
551 static void sock_daemon_run_reconfigure_done(struct tevent_req
*subreq
);
552 static void sock_daemon_run_shutdown(struct tevent_req
*req
);
553 static void sock_daemon_run_shutdown_done(struct tevent_req
*subreq
);
554 static void sock_daemon_run_exit(struct tevent_req
*req
);
555 static bool sock_daemon_run_socket_listen(struct tevent_req
*req
);
556 static void sock_daemon_run_socket_fail(struct tevent_req
*subreq
);
557 static void sock_daemon_run_watch_pid(struct tevent_req
*subreq
);
558 static void sock_daemon_run_wait(struct tevent_req
*req
);
559 static void sock_daemon_run_wait_done(struct tevent_req
*subreq
);
560 static void sock_daemon_startup_notify(struct sock_daemon_context
*sockd
);
562 struct tevent_req
*sock_daemon_run_send(TALLOC_CTX
*mem_ctx
,
563 struct tevent_context
*ev
,
564 struct sock_daemon_context
*sockd
,
566 bool do_fork
, bool create_session
,
569 struct tevent_req
*req
, *subreq
;
570 struct sock_daemon_run_state
*state
;
571 struct tevent_signal
*se
;
573 req
= tevent_req_create(mem_ctx
, &state
,
574 struct sock_daemon_run_state
);
579 become_daemon(do_fork
, !create_session
, false);
581 if (pidfile
!= NULL
) {
582 int ret
= pidfile_context_create(sockd
, pidfile
,
585 tevent_req_error(req
, EEXIST
);
586 return tevent_req_post(req
, ev
);
591 state
->sockd
= sockd
;
592 state
->pid_watch
= pid_watch
;
595 subreq
= tevent_wakeup_send(state
, ev
,
596 tevent_timeval_current_ofs(0, 0));
597 if (tevent_req_nomem(subreq
, req
)) {
598 return tevent_req_post(req
, ev
);
600 tevent_req_set_callback(subreq
, sock_daemon_run_started
, req
);
602 se
= tevent_add_signal(ev
, state
, SIGHUP
, 0,
603 sock_daemon_run_signal_handler
, req
);
604 if (tevent_req_nomem(se
, req
)) {
605 return tevent_req_post(req
, ev
);
608 se
= tevent_add_signal(ev
, state
, SIGUSR1
, 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
, SIGINT
, 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
, SIGTERM
, 0,
621 sock_daemon_run_signal_handler
, req
);
622 if (tevent_req_nomem(se
, req
)) {
623 return tevent_req_post(req
, ev
);
627 subreq
= tevent_wakeup_send(state
, ev
,
628 tevent_timeval_current_ofs(1,0));
629 if (tevent_req_nomem(subreq
, req
)) {
630 return tevent_req_post(req
, ev
);
632 tevent_req_set_callback(subreq
, sock_daemon_run_watch_pid
,
639 static void sock_daemon_run_started(struct tevent_req
*subreq
)
641 struct tevent_req
*req
= tevent_req_callback_data(
642 subreq
, struct tevent_req
);
643 struct sock_daemon_run_state
*state
= tevent_req_data(
644 req
, struct sock_daemon_run_state
);
645 struct sock_daemon_context
*sockd
= state
->sockd
;
648 status
= tevent_wakeup_recv(subreq
);
651 tevent_req_error(req
, EIO
);
655 D_NOTICE("daemon started, pid=%u\n", getpid());
657 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->startup_send
!= NULL
&&
658 sockd
->funcs
->startup_recv
!= NULL
) {
659 subreq
= sockd
->funcs
->startup_send(state
, state
->ev
,
660 sockd
->private_data
);
661 if (tevent_req_nomem(subreq
, req
)) {
664 tevent_req_set_callback(subreq
, sock_daemon_run_startup_done
,
669 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->startup
!= NULL
) {
672 ret
= sockd
->funcs
->startup(sockd
->private_data
);
674 D_ERR("startup failed, ret=%d\n", ret
);
675 tevent_req_error(req
, EIO
);
679 D_NOTICE("startup completed successfully\n");
682 status
= sock_daemon_run_socket_listen(req
);
686 sock_daemon_run_wait(req
);
688 sock_daemon_startup_notify(sockd
);
691 static void sock_daemon_run_startup_done(struct tevent_req
*subreq
)
693 struct tevent_req
*req
= tevent_req_callback_data(
694 subreq
, struct tevent_req
);
695 struct sock_daemon_run_state
*state
= tevent_req_data(
696 req
, struct sock_daemon_run_state
);
697 struct sock_daemon_context
*sockd
= state
->sockd
;
701 status
= sockd
->funcs
->startup_recv(subreq
, &ret
);
704 D_ERR("startup failed, ret=%d\n", ret
);
705 tevent_req_error(req
, EIO
);
709 D_NOTICE("startup completed successfully\n");
711 status
= sock_daemon_run_socket_listen(req
);
715 sock_daemon_run_wait(req
);
717 sock_daemon_startup_notify(sockd
);
720 static void sock_daemon_run_signal_handler(struct tevent_context
*ev
,
721 struct tevent_signal
*se
,
722 int signum
, int count
, void *siginfo
,
725 struct tevent_req
*req
= talloc_get_type_abort(
726 private_data
, struct tevent_req
);
727 struct sock_daemon_run_state
*state
= tevent_req_data(
728 req
, struct sock_daemon_run_state
);
730 D_NOTICE("Received signal %d\n", signum
);
732 if (signum
== SIGHUP
|| signum
== SIGUSR1
) {
733 sock_daemon_run_reconfigure(req
);
737 if (signum
== SIGINT
|| signum
== SIGTERM
) {
738 state
->exit_code
= EINTR
;
739 sock_daemon_run_shutdown(req
);
743 static void sock_daemon_run_reconfigure(struct tevent_req
*req
)
745 struct tevent_req
*subreq
;
746 struct sock_daemon_run_state
*state
= tevent_req_data(
747 req
, struct sock_daemon_run_state
);
748 struct sock_daemon_context
*sockd
= state
->sockd
;
750 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->reconfigure_send
!= NULL
&&
751 sockd
->funcs
->reconfigure_recv
!= NULL
) {
752 subreq
= sockd
->funcs
->reconfigure_send(state
, state
->ev
,
753 sockd
->private_data
);
754 if (tevent_req_nomem(subreq
, req
)) {
757 tevent_req_set_callback(subreq
,
758 sock_daemon_run_reconfigure_done
, req
);
762 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->reconfigure
!= NULL
) {
765 ret
= sockd
->funcs
->reconfigure(sockd
->private_data
);
767 D_ERR("reconfigure failed, ret=%d\n", ret
);
771 D_NOTICE("reconfigure completed successfully\n");
775 static void sock_daemon_run_reconfigure_done(struct tevent_req
*subreq
)
777 struct tevent_req
*req
= tevent_req_callback_data(
778 subreq
, struct tevent_req
);
779 struct sock_daemon_run_state
*state
= tevent_req_data(
780 req
, struct sock_daemon_run_state
);
781 struct sock_daemon_context
*sockd
= state
->sockd
;
785 status
= sockd
->funcs
->reconfigure_recv(subreq
, &ret
);
788 D_ERR("reconfigure failed, ret=%d\n", ret
);
792 D_NOTICE("reconfigure completed successfully\n");
795 static void sock_daemon_run_shutdown(struct tevent_req
*req
)
797 struct tevent_req
*subreq
;
798 struct sock_daemon_run_state
*state
= tevent_req_data(
799 req
, struct sock_daemon_run_state
);
800 struct sock_daemon_context
*sockd
= state
->sockd
;
801 struct sock_socket
*sock
;
803 D_NOTICE("Shutting down\n");
805 while ((sock
= sockd
->socket_list
) != NULL
) {
806 DLIST_REMOVE(sockd
->socket_list
, sock
);
810 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->shutdown_send
!= NULL
&&
811 sockd
->funcs
->shutdown_recv
!= NULL
) {
812 subreq
= sockd
->funcs
->shutdown_send(state
, state
->ev
,
813 sockd
->private_data
);
814 if (subreq
== NULL
) {
815 sock_daemon_run_exit(req
);
818 tevent_req_set_callback(subreq
, sock_daemon_run_shutdown_done
,
823 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->shutdown
!= NULL
) {
824 sockd
->funcs
->shutdown(sockd
->private_data
);
827 sock_daemon_run_exit(req
);
830 static void sock_daemon_run_shutdown_done(struct tevent_req
*subreq
)
832 struct tevent_req
*req
= tevent_req_callback_data(
833 subreq
, struct tevent_req
);
834 struct sock_daemon_run_state
*state
= tevent_req_data(
835 req
, struct sock_daemon_run_state
);
836 struct sock_daemon_context
*sockd
= state
->sockd
;
838 sockd
->funcs
->shutdown_recv(subreq
);
841 sock_daemon_run_exit(req
);
844 static void sock_daemon_run_exit(struct tevent_req
*req
)
846 struct sock_daemon_run_state
*state
= tevent_req_data(
847 req
, struct sock_daemon_run_state
);
848 struct sock_daemon_context
*sockd
= state
->sockd
;
850 TALLOC_FREE(sockd
->pid_ctx
);
852 if (state
->exit_code
== 0) {
853 tevent_req_done(req
);
855 tevent_req_error(req
, state
->exit_code
);
859 static bool sock_daemon_run_socket_listen(struct tevent_req
*req
)
861 struct tevent_req
*subreq
;
862 struct sock_daemon_run_state
*state
= tevent_req_data(
863 req
, struct sock_daemon_run_state
);
864 struct sock_daemon_context
*sockd
= state
->sockd
;
865 struct sock_socket
*sock
;
866 bool remove_before_use
= false;
868 if (sockd
->pid_ctx
!= NULL
) {
869 remove_before_use
= true;
871 for (sock
= sockd
->socket_list
; sock
!= NULL
; sock
= sock
->next
) {
872 subreq
= sock_socket_start_send(state
, state
->ev
, sock
,
874 if (tevent_req_nomem(subreq
, req
)) {
877 tevent_req_set_callback(subreq
, sock_daemon_run_socket_fail
,
884 static void sock_daemon_run_socket_fail(struct tevent_req
*subreq
)
886 struct tevent_req
*req
= tevent_req_callback_data(
887 subreq
, struct tevent_req
);
888 struct sock_daemon_run_state
*state
= tevent_req_data(
889 req
, struct sock_daemon_run_state
);
890 const char *sockpath
= NULL
;
894 status
= sock_socket_start_recv(subreq
, &ret
, state
, &sockpath
);
897 D_ERR("socket %s closed unexpectedly\n", sockpath
);
898 state
->exit_code
= ret
;
900 state
->exit_code
= 0;
903 sock_daemon_run_shutdown(req
);
906 static void sock_daemon_run_watch_pid(struct tevent_req
*subreq
)
908 struct tevent_req
*req
= tevent_req_callback_data(
909 subreq
, struct tevent_req
);
910 struct sock_daemon_run_state
*state
= tevent_req_data(
911 req
, struct sock_daemon_run_state
);
915 status
= tevent_wakeup_recv(subreq
);
918 tevent_req_error(req
, EIO
);
922 ret
= kill(state
->pid_watch
, 0);
924 if (errno
== ESRCH
) {
925 D_ERR("PID %d gone away, exiting\n", state
->pid_watch
);
926 state
->exit_code
= ESRCH
;
927 sock_daemon_run_shutdown(req
);
930 D_ERR("Failed to check PID status %d, ret=%d\n",
931 state
->pid_watch
, errno
);
935 subreq
= tevent_wakeup_send(state
, state
->ev
,
936 tevent_timeval_current_ofs(5,0));
937 if (tevent_req_nomem(subreq
, req
)) {
940 tevent_req_set_callback(subreq
, sock_daemon_run_watch_pid
, req
);
943 static void sock_daemon_run_wait(struct tevent_req
*req
)
945 struct tevent_req
*subreq
;
946 struct sock_daemon_run_state
*state
= tevent_req_data(
947 req
, struct sock_daemon_run_state
);
948 struct sock_daemon_context
*sockd
= state
->sockd
;
950 if (sockd
->funcs
!= NULL
&& sockd
->funcs
->wait_send
!= NULL
&&
951 sockd
->funcs
->wait_recv
!= NULL
) {
952 subreq
= sockd
->funcs
->wait_send(state
, state
->ev
,
953 sockd
->private_data
);
954 if (tevent_req_nomem(subreq
, req
)) {
957 tevent_req_set_callback(subreq
, sock_daemon_run_wait_done
,
962 static void sock_daemon_run_wait_done(struct tevent_req
*subreq
)
964 struct tevent_req
*req
= tevent_req_callback_data(
965 subreq
, struct tevent_req
);
966 struct sock_daemon_run_state
*state
= tevent_req_data(
967 req
, struct sock_daemon_run_state
);
968 struct sock_daemon_context
*sockd
= state
->sockd
;
972 status
= sockd
->funcs
->wait_recv(subreq
, &ret
);
975 state
->exit_code
= ret
;
977 state
->exit_code
= 0;
980 sock_daemon_run_shutdown(req
);
983 static void sock_daemon_startup_notify(struct sock_daemon_context
*sockd
)
985 if (sockd
->startup_fd
!= -1) {
986 unsigned int zero
= 0;
989 num
= sys_write(sockd
->startup_fd
, &zero
, sizeof(zero
));
990 if (num
!= sizeof(zero
)) {
991 D_WARNING("Failed to write zero to pipe FD\n");
996 bool sock_daemon_run_recv(struct tevent_req
*req
, int *perr
)
1000 if (tevent_req_is_unix_error(req
, &ret
)) {
1010 int sock_daemon_run(struct tevent_context
*ev
,
1011 struct sock_daemon_context
*sockd
,
1012 const char *pidfile
,
1013 bool do_fork
, bool create_session
,
1016 struct tevent_req
*req
;
1020 req
= sock_daemon_run_send(ev
, ev
, sockd
,
1021 pidfile
, do_fork
, create_session
, pid_watch
);
1026 tevent_req_poll(req
, ev
);
1028 status
= sock_daemon_run_recv(req
, &ret
);