s3:include: Remove trailing whitepaces in MacExtensions.h
[Samba.git] / ctdb / common / sock_daemon.c
blobe31a36445b51c856f87189cf20333e59cc8f8eba
1 /*
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/>.
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
25 #include <talloc.h>
26 #include <tevent.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"
43 struct sock_socket {
44 struct sock_socket *prev, *next;
46 const char *sockpath;
47 struct sock_socket_funcs *funcs;
48 void *private_data;
50 int fd;
51 struct tevent_req *req;
54 struct sock_client {
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;
64 int fd;
65 struct comm_context *comm;
67 struct sock_client *client;
70 struct sock_daemon_context {
71 struct sock_daemon_funcs *funcs;
72 void *private_data;
74 struct pidfile_context *pid_ctx;
75 struct sock_socket *socket_list;
76 int startup_fd;
80 * Process a single client
83 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
84 void *private_data);
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,
93 int client_fd,
94 struct sock_client *client,
95 struct sock_client_context **result)
97 struct sock_client_context *client_ctx;
98 int ret;
100 client_ctx = talloc_zero(mem_ctx, struct sock_client_context);
101 if (client_ctx == NULL) {
102 return ENOMEM;
105 client_ctx->ev = ev;
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,
113 &client_ctx->comm);
114 if (ret != 0) {
115 talloc_free(client_ctx);
116 return ret;
119 if (sock->funcs->connect != NULL) {
120 pid_t pid;
121 bool status;
123 (void) ctdb_get_peer_pid(client_fd, &pid);
125 status = sock->funcs->connect(client_ctx,
126 pid,
127 sock->private_data);
128 if (! status) {
129 talloc_free(client_ctx);
130 close(client_fd);
131 return 0;
135 talloc_set_destructor(client_ctx, sock_client_context_destructor);
137 *result = client_ctx;
138 return 0;
141 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
142 void *private_data)
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,
151 sock->private_data);
152 if (subreq == NULL) {
153 talloc_free(client_ctx);
154 return;
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;
164 int ret;
165 bool status;
167 status = sock->funcs->read_recv(subreq, &ret);
168 if (! status) {
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);
194 client_ctx->fd = -1;
197 return 0;
201 * Process a single listening socket
204 static int socket_setup(const char *sockpath, bool remove_before_use)
206 struct sockaddr_un addr;
207 size_t len;
208 int ret, fd;
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);
216 return -1;
219 fd = socket(AF_UNIX, SOCK_STREAM, 0);
220 if (fd == -1) {
221 D_ERR("socket create failed - %s\n", sockpath);
222 return -1;
225 ret = set_blocking(fd, false);
226 if (ret != 0) {
227 D_ERR("socket set nonblocking failed - %s\n", sockpath);
228 close(fd);
229 return -1;
232 if (remove_before_use) {
233 unlink(sockpath);
236 ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
237 if (ret != 0) {
238 D_ERR("socket bind failed - %s\n", sockpath);
239 close(fd);
240 return -1;
243 ret = listen(fd, 10);
244 if (ret != 0) {
245 D_ERR("socket listen failed - %s\n", sockpath);
246 close(fd);
247 return -1;
250 D_NOTICE("listening on %s\n", sockpath);
252 return fd;
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,
259 void *private_data,
260 struct sock_socket **result)
262 struct sock_socket *sock;
264 if (funcs == NULL) {
265 return EINVAL;
267 if (funcs->read_send == NULL || funcs->read_recv == NULL) {
268 return EINVAL;
271 sock = talloc_zero(mem_ctx, struct sock_socket);
272 if (sock == NULL) {
273 return ENOMEM;
276 sock->sockpath = talloc_strdup(sock, sockpath);
277 if (sock->sockpath == NULL) {
278 talloc_free(sock);
279 return ENOMEM;
281 sock->funcs = funcs;
282 sock->private_data = private_data;
283 sock->fd = -1;
285 talloc_set_destructor(sock, sock_socket_destructor);
287 *result = sock;
288 return 0;
291 static int sock_socket_destructor(struct sock_socket *sock)
293 TALLOC_FREE(sock->req);
295 if (sock->fd != -1) {
296 close(sock->fd);
297 sock->fd = -1;
300 unlink(sock->sockpath);
301 return 0;
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);
327 if (req == NULL) {
328 return NULL;
331 state->ev = ev;
332 state->sock = sock;
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);
348 sock->req = req;
350 return 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) {
359 talloc_free(client);
362 return 0;
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;
372 int client_fd, ret;
374 client_fd = accept_recv(subreq, NULL, NULL, &ret);
375 TALLOC_FREE(subreq);
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)) {
382 return;
384 tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
386 if (client_fd == -1) {
387 return;
390 client = talloc_zero(state, struct sock_client);
391 if (tevent_req_nomem(client, req)) {
392 close(client_fd);
393 return;
396 client->req = req;
398 ret = sock_client_context_init(client, state->ev, state->sock,
399 client_fd, client, &client->client_ctx);
400 if (ret != 0) {
401 talloc_free(client);
402 return;
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);
417 return 0;
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);
425 int ret;
427 state->sock->req = NULL;
429 if (tevent_req_is_unix_error(req, &ret)) {
430 if (perr != NULL) {
431 *perr = ret;
433 return false;
436 if (sockpath != NULL) {
437 *sockpath = talloc_steal(mem_ctx, state->sock->sockpath);
440 return true;
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);
456 return req;
459 bool sock_socket_write_recv(struct tevent_req *req, int *perr)
461 int ret;
462 bool status;
464 status = comm_write_recv(req, &ret);
465 if (! status) {
466 if (perr != NULL) {
467 *perr = ret;
471 return status;
475 * Socket daemon
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,
481 void *private_data,
482 struct sock_daemon_context **out)
484 struct sock_daemon_context *sockd;
485 int ret;
487 sockd = talloc_zero(mem_ctx, struct sock_daemon_context);
488 if (sockd == NULL) {
489 return ENOMEM;
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);
497 if (ret != 0) {
498 fprintf(stderr,
499 "Failed to initialize logging, logging=%s, debug=%s\n",
500 logging, debug_level);
501 return ret;
504 *out = sockd;
505 return 0;
508 int sock_daemon_add_unix(struct sock_daemon_context *sockd,
509 const char *sockpath,
510 struct sock_socket_funcs *funcs,
511 void *private_data)
513 struct sock_socket *sock;
514 int ret;
516 ret = sock_socket_init(sockd, sockpath, funcs, private_data, &sock);
517 if (ret != 0) {
518 return ret;
522 DLIST_ADD(sockd->socket_list, sock);
523 return 0;
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");
530 return false;
533 sockd->startup_fd = fd;
534 return true;
538 * Run socket daemon
541 struct sock_daemon_run_state {
542 struct tevent_context *ev;
543 struct sock_daemon_context *sockd;
544 pid_t pid_watch;
546 int fd;
547 int exit_code;
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,
555 void *private_data);
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_reopen_logs(struct tevent_req *req);
559 static void sock_daemon_run_reopen_logs_done(struct tevent_req *subreq);
560 static void sock_daemon_run_shutdown(struct tevent_req *req);
561 static void sock_daemon_run_shutdown_done(struct tevent_req *subreq);
562 static void sock_daemon_run_exit(struct tevent_req *req);
563 static bool sock_daemon_run_socket_listen(struct tevent_req *req);
564 static void sock_daemon_run_socket_fail(struct tevent_req *subreq);
565 static void sock_daemon_run_watch_pid(struct tevent_req *subreq);
566 static void sock_daemon_run_wait(struct tevent_req *req);
567 static void sock_daemon_run_wait_done(struct tevent_req *subreq);
568 static void sock_daemon_startup_notify(struct sock_daemon_context *sockd);
570 struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
571 struct tevent_context *ev,
572 struct sock_daemon_context *sockd,
573 const char *pidfile,
574 bool do_fork, bool create_session,
575 pid_t pid_watch)
577 struct tevent_req *req, *subreq;
578 struct sock_daemon_run_state *state;
579 struct tevent_signal *se;
581 req = tevent_req_create(mem_ctx, &state,
582 struct sock_daemon_run_state);
583 if (req == NULL) {
584 return NULL;
587 become_daemon(do_fork, !create_session, false);
589 if (pidfile != NULL) {
590 int ret = pidfile_context_create(sockd, pidfile,
591 &sockd->pid_ctx);
592 if (ret != 0) {
593 tevent_req_error(req, EEXIST);
594 return tevent_req_post(req, ev);
598 state->ev = ev;
599 state->sockd = sockd;
600 state->pid_watch = pid_watch;
601 state->fd = -1;
603 subreq = tevent_wakeup_send(state, ev,
604 tevent_timeval_current_ofs(0, 0));
605 if (tevent_req_nomem(subreq, req)) {
606 return tevent_req_post(req, ev);
608 tevent_req_set_callback(subreq, sock_daemon_run_started, req);
610 se = tevent_add_signal(ev, state, SIGHUP, 0,
611 sock_daemon_run_signal_handler, req);
612 if (tevent_req_nomem(se, req)) {
613 return tevent_req_post(req, ev);
616 se = tevent_add_signal(ev, state, SIGUSR1, 0,
617 sock_daemon_run_signal_handler, req);
618 if (tevent_req_nomem(se, req)) {
619 return tevent_req_post(req, ev);
622 se = tevent_add_signal(ev, state, SIGINT, 0,
623 sock_daemon_run_signal_handler, req);
624 if (tevent_req_nomem(se, req)) {
625 return tevent_req_post(req, ev);
628 se = tevent_add_signal(ev, state, SIGTERM, 0,
629 sock_daemon_run_signal_handler, req);
630 if (tevent_req_nomem(se, req)) {
631 return tevent_req_post(req, ev);
634 if (pid_watch > 1) {
635 subreq = tevent_wakeup_send(state, ev,
636 tevent_timeval_current_ofs(1,0));
637 if (tevent_req_nomem(subreq, req)) {
638 return tevent_req_post(req, ev);
640 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid,
641 req);
644 return req;
647 static void sock_daemon_run_started(struct tevent_req *subreq)
649 struct tevent_req *req = tevent_req_callback_data(
650 subreq, struct tevent_req);
651 struct sock_daemon_run_state *state = tevent_req_data(
652 req, struct sock_daemon_run_state);
653 struct sock_daemon_context *sockd = state->sockd;
654 bool status;
656 status = tevent_wakeup_recv(subreq);
657 TALLOC_FREE(subreq);
658 if (! status) {
659 tevent_req_error(req, EIO);
660 return;
663 D_NOTICE("daemon started, pid=%u\n", getpid());
665 if (sockd->funcs != NULL && sockd->funcs->startup_send != NULL &&
666 sockd->funcs->startup_recv != NULL) {
667 subreq = sockd->funcs->startup_send(state, state->ev,
668 sockd->private_data);
669 if (tevent_req_nomem(subreq, req)) {
670 return;
672 tevent_req_set_callback(subreq, sock_daemon_run_startup_done,
673 req);
674 return;
677 if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
678 int ret;
680 ret = sockd->funcs->startup(sockd->private_data);
681 if (ret != 0) {
682 D_ERR("startup failed, ret=%d\n", ret);
683 tevent_req_error(req, EIO);
684 return;
687 D_NOTICE("startup completed successfully\n");
690 status = sock_daemon_run_socket_listen(req);
691 if (! status) {
692 return;
694 sock_daemon_run_wait(req);
696 sock_daemon_startup_notify(sockd);
699 static void sock_daemon_run_startup_done(struct tevent_req *subreq)
701 struct tevent_req *req = tevent_req_callback_data(
702 subreq, struct tevent_req);
703 struct sock_daemon_run_state *state = tevent_req_data(
704 req, struct sock_daemon_run_state);
705 struct sock_daemon_context *sockd = state->sockd;
706 int ret;
707 bool status;
709 status = sockd->funcs->startup_recv(subreq, &ret);
710 TALLOC_FREE(subreq);
711 if (! status) {
712 D_ERR("startup failed, ret=%d\n", ret);
713 tevent_req_error(req, EIO);
714 return;
717 D_NOTICE("startup completed successfully\n");
719 status = sock_daemon_run_socket_listen(req);
720 if (! status) {
721 return;
723 sock_daemon_run_wait(req);
725 sock_daemon_startup_notify(sockd);
728 static void sock_daemon_run_signal_handler(struct tevent_context *ev,
729 struct tevent_signal *se,
730 int signum, int count, void *siginfo,
731 void *private_data)
733 struct tevent_req *req = talloc_get_type_abort(
734 private_data, struct tevent_req);
735 struct sock_daemon_run_state *state = tevent_req_data(
736 req, struct sock_daemon_run_state);
738 D_NOTICE("Received signal %d\n", signum);
740 if (signum == SIGUSR1) {
741 sock_daemon_run_reconfigure(req);
742 return;
745 if (signum == SIGHUP) {
746 sock_daemon_run_reopen_logs(req);
747 return;
750 if (signum == SIGINT || signum == SIGTERM) {
751 state->exit_code = EINTR;
752 sock_daemon_run_shutdown(req);
756 static void sock_daemon_run_reconfigure(struct tevent_req *req)
758 struct tevent_req *subreq;
759 struct sock_daemon_run_state *state = tevent_req_data(
760 req, struct sock_daemon_run_state);
761 struct sock_daemon_context *sockd = state->sockd;
763 if (sockd->funcs != NULL && sockd->funcs->reconfigure_send != NULL &&
764 sockd->funcs->reconfigure_recv != NULL) {
765 subreq = sockd->funcs->reconfigure_send(state, state->ev,
766 sockd->private_data);
767 if (tevent_req_nomem(subreq, req)) {
768 return;
770 tevent_req_set_callback(subreq,
771 sock_daemon_run_reconfigure_done, req);
772 return;
775 if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
776 int ret;
778 ret = sockd->funcs->reconfigure(sockd->private_data);
779 if (ret != 0) {
780 D_ERR("reconfigure failed, ret=%d\n", ret);
781 return;
784 D_NOTICE("reconfigure completed successfully\n");
788 static void sock_daemon_run_reconfigure_done(struct tevent_req *subreq)
790 struct tevent_req *req = tevent_req_callback_data(
791 subreq, struct tevent_req);
792 struct sock_daemon_run_state *state = tevent_req_data(
793 req, struct sock_daemon_run_state);
794 struct sock_daemon_context *sockd = state->sockd;
795 int ret;
796 bool status;
798 status = sockd->funcs->reconfigure_recv(subreq, &ret);
799 TALLOC_FREE(subreq);
800 if (! status) {
801 D_ERR("reconfigure failed, ret=%d\n", ret);
802 return;
805 D_NOTICE("reconfigure completed successfully\n");
808 static void sock_daemon_run_reopen_logs(struct tevent_req *req)
810 struct tevent_req *subreq;
811 struct sock_daemon_run_state *state = tevent_req_data(
812 req, struct sock_daemon_run_state);
813 struct sock_daemon_context *sockd = state->sockd;
815 if (sockd->funcs != NULL && sockd->funcs->reopen_logs_send != NULL &&
816 sockd->funcs->reopen_logs_recv != NULL) {
817 subreq = sockd->funcs->reopen_logs_send(state, state->ev,
818 sockd->private_data);
819 if (tevent_req_nomem(subreq, req)) {
820 return;
822 tevent_req_set_callback(subreq,
823 sock_daemon_run_reopen_logs_done, req);
824 return;
827 if (sockd->funcs != NULL && sockd->funcs->reopen_logs != NULL) {
828 int ret;
830 ret = sockd->funcs->reopen_logs(sockd->private_data);
831 if (ret != 0) {
832 D_ERR("reopen logs, ret=%d\n", ret);
833 return;
836 D_NOTICE("reopen logs completed successfully\n");
840 static void sock_daemon_run_reopen_logs_done(struct tevent_req *subreq)
842 struct tevent_req *req = tevent_req_callback_data(
843 subreq, struct tevent_req);
844 struct sock_daemon_run_state *state = tevent_req_data(
845 req, struct sock_daemon_run_state);
846 struct sock_daemon_context *sockd = state->sockd;
847 int ret;
848 bool status;
850 status = sockd->funcs->reopen_logs_recv(subreq, &ret);
851 TALLOC_FREE(subreq);
852 if (! status) {
853 D_ERR("reopen logs failed, ret=%d\n", ret);
854 return;
857 D_NOTICE("reopen logs completed successfully\n");
860 static void sock_daemon_run_shutdown(struct tevent_req *req)
862 struct tevent_req *subreq;
863 struct sock_daemon_run_state *state = tevent_req_data(
864 req, struct sock_daemon_run_state);
865 struct sock_daemon_context *sockd = state->sockd;
866 struct sock_socket *sock;
868 D_NOTICE("Shutting down\n");
870 while ((sock = sockd->socket_list) != NULL) {
871 DLIST_REMOVE(sockd->socket_list, sock);
872 TALLOC_FREE(sock);
875 if (sockd->funcs != NULL && sockd->funcs->shutdown_send != NULL &&
876 sockd->funcs->shutdown_recv != NULL) {
877 subreq = sockd->funcs->shutdown_send(state, state->ev,
878 sockd->private_data);
879 if (subreq == NULL) {
880 sock_daemon_run_exit(req);
881 return;
883 tevent_req_set_callback(subreq, sock_daemon_run_shutdown_done,
884 req);
885 return;
888 if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) {
889 sockd->funcs->shutdown(sockd->private_data);
892 sock_daemon_run_exit(req);
895 static void sock_daemon_run_shutdown_done(struct tevent_req *subreq)
897 struct tevent_req *req = tevent_req_callback_data(
898 subreq, struct tevent_req);
899 struct sock_daemon_run_state *state = tevent_req_data(
900 req, struct sock_daemon_run_state);
901 struct sock_daemon_context *sockd = state->sockd;
903 sockd->funcs->shutdown_recv(subreq);
904 TALLOC_FREE(subreq);
906 sock_daemon_run_exit(req);
909 static void sock_daemon_run_exit(struct tevent_req *req)
911 struct sock_daemon_run_state *state = tevent_req_data(
912 req, struct sock_daemon_run_state);
913 struct sock_daemon_context *sockd = state->sockd;
915 TALLOC_FREE(sockd->pid_ctx);
917 if (state->exit_code == 0) {
918 tevent_req_done(req);
919 } else {
920 tevent_req_error(req, state->exit_code);
924 static bool sock_daemon_run_socket_listen(struct tevent_req *req)
926 struct tevent_req *subreq;
927 struct sock_daemon_run_state *state = tevent_req_data(
928 req, struct sock_daemon_run_state);
929 struct sock_daemon_context *sockd = state->sockd;
930 struct sock_socket *sock;
931 bool remove_before_use = false;
933 if (sockd->pid_ctx != NULL) {
934 remove_before_use = true;
936 for (sock = sockd->socket_list; sock != NULL; sock = sock->next) {
937 subreq = sock_socket_start_send(state, state->ev, sock,
938 remove_before_use);
939 if (tevent_req_nomem(subreq, req)) {
940 return false;
942 tevent_req_set_callback(subreq, sock_daemon_run_socket_fail,
943 req);
946 return true;
949 static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
951 struct tevent_req *req = tevent_req_callback_data(
952 subreq, struct tevent_req);
953 struct sock_daemon_run_state *state = tevent_req_data(
954 req, struct sock_daemon_run_state);
955 const char *sockpath = "INVALID";
956 int ret = 0;
957 bool status;
959 status = sock_socket_start_recv(subreq, &ret, state, &sockpath);
960 TALLOC_FREE(subreq);
961 if (! status) {
962 D_ERR("socket %s closed unexpectedly\n", sockpath);
963 state->exit_code = ret;
964 } else {
965 state->exit_code = 0;
968 sock_daemon_run_shutdown(req);
971 static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
973 struct tevent_req *req = tevent_req_callback_data(
974 subreq, struct tevent_req);
975 struct sock_daemon_run_state *state = tevent_req_data(
976 req, struct sock_daemon_run_state);
977 int ret;
978 bool status;
980 status = tevent_wakeup_recv(subreq);
981 TALLOC_FREE(subreq);
982 if (! status) {
983 tevent_req_error(req, EIO);
984 return;
987 ret = kill(state->pid_watch, 0);
988 if (ret == -1) {
989 if (errno == ESRCH) {
990 D_ERR("PID %d gone away, exiting\n", state->pid_watch);
991 state->exit_code = ESRCH;
992 sock_daemon_run_shutdown(req);
993 return;
994 } else {
995 D_ERR("Failed to check PID status %d, ret=%d\n",
996 state->pid_watch, errno);
1000 subreq = tevent_wakeup_send(state, state->ev,
1001 tevent_timeval_current_ofs(5,0));
1002 if (tevent_req_nomem(subreq, req)) {
1003 return;
1005 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
1008 static void sock_daemon_run_wait(struct tevent_req *req)
1010 struct tevent_req *subreq;
1011 struct sock_daemon_run_state *state = tevent_req_data(
1012 req, struct sock_daemon_run_state);
1013 struct sock_daemon_context *sockd = state->sockd;
1015 if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL &&
1016 sockd->funcs->wait_recv != NULL) {
1017 subreq = sockd->funcs->wait_send(state, state->ev,
1018 sockd->private_data);
1019 if (tevent_req_nomem(subreq, req)) {
1020 return;
1022 tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
1023 req);
1027 static void sock_daemon_run_wait_done(struct tevent_req *subreq)
1029 struct tevent_req *req = tevent_req_callback_data(
1030 subreq, struct tevent_req);
1031 struct sock_daemon_run_state *state = tevent_req_data(
1032 req, struct sock_daemon_run_state);
1033 struct sock_daemon_context *sockd = state->sockd;
1034 int ret = 0;
1035 bool status;
1037 status = sockd->funcs->wait_recv(subreq, &ret);
1038 TALLOC_FREE(subreq);
1039 if (! status) {
1040 state->exit_code = ret;
1041 } else {
1042 state->exit_code = 0;
1045 sock_daemon_run_shutdown(req);
1048 static void sock_daemon_startup_notify(struct sock_daemon_context *sockd)
1050 if (sockd->startup_fd != -1) {
1051 unsigned int zero = 0;
1052 ssize_t num;
1054 num = sys_write(sockd->startup_fd, &zero, sizeof(zero));
1055 if (num != sizeof(zero)) {
1056 D_WARNING("Failed to write zero to pipe FD\n");
1061 bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
1063 int ret;
1065 if (tevent_req_is_unix_error(req, &ret)) {
1066 if (perr != NULL) {
1067 *perr = ret;
1069 return false;
1072 return true;
1075 int sock_daemon_run(struct tevent_context *ev,
1076 struct sock_daemon_context *sockd,
1077 const char *pidfile,
1078 bool do_fork, bool create_session,
1079 pid_t pid_watch)
1081 struct tevent_req *req;
1082 int ret;
1083 bool status;
1085 req = sock_daemon_run_send(ev, ev, sockd,
1086 pidfile, do_fork, create_session, pid_watch);
1087 if (req == NULL) {
1088 return ENOMEM;
1091 tevent_req_poll(req, ev);
1093 status = sock_daemon_run_recv(req, &ret);
1094 TALLOC_FREE(req);
1095 if (! status) {
1096 return ret;
1099 return 0;