ctdb-common: Do not use sock->req outside sock_socket functions
[Samba.git] / ctdb / common / sock_daemon.c
bloba41a5d5a7ea6a1361756b40db70795310d5f15da
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"
35 #include "common/logging.h"
36 #include "common/reqid.h"
37 #include "common/comm.h"
38 #include "common/pidfile.h"
39 #include "common/sock_daemon.h"
41 struct sock_socket {
42 struct sock_socket *prev, *next;
44 const char *sockpath;
45 struct sock_socket_funcs *funcs;
46 void *private_data;
48 int fd;
49 struct tevent_req *req;
52 struct sock_client {
53 struct sock_client *prev, *next;
55 struct tevent_req *req;
56 struct sock_client_context *client_ctx;
59 struct sock_client_context {
60 struct tevent_context *ev;
61 struct sock_socket *sock;
62 int fd;
63 struct comm_context *comm;
65 struct sock_client *client;
68 struct sock_daemon_context {
69 struct sock_daemon_funcs *funcs;
70 void *private_data;
72 struct pidfile_context *pid_ctx;
73 struct sock_socket *socket_list;
77 * Process a single client
80 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
81 void *private_data);
82 static void sock_client_read_done(struct tevent_req *subreq);
83 static void sock_client_dead_handler(void *private_data);
84 static int sock_client_context_destructor(
85 struct sock_client_context *client_ctx);
87 static int sock_client_context_init(TALLOC_CTX *mem_ctx,
88 struct tevent_context *ev,
89 struct sock_socket *sock,
90 int client_fd,
91 struct sock_client *client,
92 struct sock_client_context **result)
94 struct sock_client_context *client_ctx;
95 int ret;
97 client_ctx = talloc_zero(mem_ctx, struct sock_client_context);
98 if (client_ctx == NULL) {
99 return ENOMEM;
102 client_ctx->ev = ev;
103 client_ctx->sock = sock;
104 client_ctx->fd = client_fd;
105 client_ctx->client = client;
107 ret = comm_setup(client_ctx, ev, client_fd,
108 sock_client_read_handler, client_ctx,
109 sock_client_dead_handler, client_ctx,
110 &client_ctx->comm);
111 if (ret != 0) {
112 talloc_free(client_ctx);
113 return ret;
116 if (sock->funcs->connect != NULL) {
117 bool status;
119 status = sock->funcs->connect(client_ctx, sock->private_data);
120 if (! status) {
121 talloc_free(client_ctx);
122 close(client_fd);
123 return 0;
127 talloc_set_destructor(client_ctx, sock_client_context_destructor);
129 *result = client_ctx;
130 return 0;
133 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
134 void *private_data)
136 struct sock_client_context *client_ctx = talloc_get_type_abort(
137 private_data, struct sock_client_context);
138 struct sock_socket *sock = client_ctx->sock;
139 struct tevent_req *subreq;
141 subreq = sock->funcs->read_send(client_ctx, client_ctx->ev,
142 client_ctx, buf, buflen,
143 sock->private_data);
144 if (subreq == NULL) {
145 talloc_free(client_ctx);
146 return;
148 tevent_req_set_callback(subreq, sock_client_read_done, client_ctx);
151 static void sock_client_read_done(struct tevent_req *subreq)
153 struct sock_client_context *client_ctx = tevent_req_callback_data(
154 subreq, struct sock_client_context);
155 struct sock_socket *sock = client_ctx->sock;
156 int ret;
157 bool status;
159 status = sock->funcs->read_recv(subreq, &ret);
160 if (! status) {
161 D_ERR("client read failed with ret=%d\n", ret);
162 talloc_free(client_ctx);
166 static void sock_client_dead_handler(void *private_data)
168 struct sock_client_context *client_ctx = talloc_get_type_abort(
169 private_data, struct sock_client_context);
170 struct sock_socket *sock = client_ctx->sock;
172 if (sock->funcs->disconnect != NULL) {
173 sock->funcs->disconnect(client_ctx, sock->private_data);
176 talloc_free(client_ctx);
179 static int sock_client_context_destructor(
180 struct sock_client_context *client_ctx)
182 TALLOC_FREE(client_ctx->client);
183 TALLOC_FREE(client_ctx->comm);
184 if (client_ctx->fd != -1) {
185 close(client_ctx->fd);
186 client_ctx->fd = -1;
189 return 0;
193 * Process a single listening socket
196 static int socket_setup(const char *sockpath, bool remove_before_use)
198 struct sockaddr_un addr;
199 size_t len;
200 int ret, fd;
202 memset(&addr, 0, sizeof(addr));
203 addr.sun_family = AF_UNIX;
205 len = strlcpy(addr.sun_path, sockpath, sizeof(addr.sun_path));
206 if (len >= sizeof(addr.sun_path)) {
207 D_ERR("socket path too long: %s\n", sockpath);
208 return -1;
211 fd = socket(AF_UNIX, SOCK_STREAM, 0);
212 if (fd == -1) {
213 D_ERR("socket create failed - %s\n", sockpath);
214 return -1;
217 ret = set_blocking(fd, false);
218 if (ret != 0) {
219 D_ERR("socket set nonblocking failed - %s\n", sockpath);
220 close(fd);
221 return -1;
224 if (remove_before_use) {
225 unlink(sockpath);
228 ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
229 if (ret != 0) {
230 D_ERR("socket bind failed - %s\n", sockpath);
231 close(fd);
232 return -1;
235 ret = listen(fd, 10);
236 if (ret != 0) {
237 D_ERR("socket listen failed - %s\n", sockpath);
238 close(fd);
239 return -1;
242 D_NOTICE("listening on %s\n", sockpath);
244 return fd;
247 static int sock_socket_destructor(struct sock_socket *sock);
249 static int sock_socket_init(TALLOC_CTX *mem_ctx, const char *sockpath,
250 struct sock_socket_funcs *funcs,
251 void *private_data,
252 struct sock_socket **result)
254 struct sock_socket *sock;
256 if (funcs == NULL) {
257 return EINVAL;
259 if (funcs->read_send == NULL || funcs->read_recv == NULL) {
260 return EINVAL;
263 sock = talloc_zero(mem_ctx, struct sock_socket);
264 if (sock == NULL) {
265 return ENOMEM;
268 sock->sockpath = sockpath;
269 sock->funcs = funcs;
270 sock->private_data = private_data;
271 sock->fd = -1;
273 talloc_set_destructor(sock, sock_socket_destructor);
275 *result = sock;
276 return 0;
279 static int sock_socket_destructor(struct sock_socket *sock)
281 TALLOC_FREE(sock->req);
283 if (sock->fd != -1) {
284 close(sock->fd);
285 sock->fd = -1;
288 unlink(sock->sockpath);
289 return 0;
293 struct sock_socket_start_state {
294 struct tevent_context *ev;
295 struct sock_socket *sock;
297 struct sock_client *client_list;
300 static int sock_socket_start_state_destructor(
301 struct sock_socket_start_state *state);
302 static void sock_socket_start_new_client(struct tevent_req *subreq);
303 static int sock_socket_start_client_destructor(struct sock_client *client);
305 static struct tevent_req *sock_socket_start_send(TALLOC_CTX *mem_ctx,
306 struct tevent_context *ev,
307 struct sock_socket *sock,
308 bool remove_before_use)
310 struct tevent_req *req, *subreq;
311 struct sock_socket_start_state *state;
313 req = tevent_req_create(mem_ctx, &state,
314 struct sock_socket_start_state);
315 if (req == NULL) {
316 return NULL;
319 state->ev = ev;
320 state->sock = sock;
322 sock->fd = socket_setup(sock->sockpath, remove_before_use);
323 if (sock->fd == -1) {
324 tevent_req_error(req, EIO);
325 return tevent_req_post(req, ev);
328 talloc_set_destructor(state, sock_socket_start_state_destructor);
330 subreq = accept_send(state, ev, sock->fd);
331 if (tevent_req_nomem(subreq, req)) {
332 return tevent_req_post(req, ev);
334 tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
336 sock->req = req;
338 return req;
341 static int sock_socket_start_state_destructor(
342 struct sock_socket_start_state *state)
344 struct sock_client *client;
346 while ((client = state->client_list) != NULL) {
347 talloc_free(client);
350 return 0;
353 static void sock_socket_start_new_client(struct tevent_req *subreq)
355 struct tevent_req *req = tevent_req_callback_data(
356 subreq, struct tevent_req);
357 struct sock_socket_start_state *state = tevent_req_data(
358 req, struct sock_socket_start_state);
359 struct sock_client *client;
360 int client_fd, ret;
362 client_fd = accept_recv(subreq, NULL, NULL, &ret);
363 TALLOC_FREE(subreq);
364 if (client_fd == -1) {
365 D_ERR("failed to accept new connection\n");
368 subreq = accept_send(state, state->ev, state->sock->fd);
369 if (tevent_req_nomem(subreq, req)) {
370 return;
372 tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
374 if (client_fd == -1) {
375 return;
378 client = talloc_zero(state, struct sock_client);
379 if (tevent_req_nomem(client, req)) {
380 close(client_fd);
381 return;
384 client->req = req;
386 ret = sock_client_context_init(client, state->ev, state->sock,
387 client_fd, client, &client->client_ctx);
388 if (ret != 0) {
389 talloc_free(client);
390 return;
393 talloc_set_destructor(client, sock_socket_start_client_destructor);
394 DLIST_ADD(state->client_list, client);
397 static int sock_socket_start_client_destructor(struct sock_client *client)
399 struct sock_socket_start_state *state = tevent_req_data(
400 client->req, struct sock_socket_start_state);
402 DLIST_REMOVE(state->client_list, client);
403 TALLOC_FREE(client->client_ctx);
405 return 0;
408 static bool sock_socket_start_recv(struct tevent_req *req, int *perr)
410 struct sock_socket_start_state *state = tevent_req_data(
411 req, struct sock_socket_start_state);
412 int ret;
414 state->sock->req = NULL;
416 if (tevent_req_is_unix_error(req, &ret)) {
417 if (perr != NULL) {
418 *perr = ret;
420 return false;
423 return true;
427 * Send message to a client
430 struct tevent_req *sock_socket_write_send(TALLOC_CTX *mem_ctx,
431 struct tevent_context *ev,
432 struct sock_client_context *client_ctx,
433 uint8_t *buf, size_t buflen)
435 struct tevent_req *req;
437 req = comm_write_send(mem_ctx, ev, client_ctx->comm, buf, buflen);
439 return req;
442 bool sock_socket_write_recv(struct tevent_req *req, int *perr)
444 int ret;
445 bool status;
447 status = comm_write_recv(req, &ret);
448 if (! status) {
449 if (perr != NULL) {
450 *perr = ret;
454 return status;
458 * Socket daemon
461 int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name,
462 const char *logging, const char *debug_level,
463 struct sock_daemon_funcs *funcs,
464 void *private_data,
465 struct sock_daemon_context **out)
467 struct sock_daemon_context *sockd;
468 int ret;
470 sockd = talloc_zero(mem_ctx, struct sock_daemon_context);
471 if (sockd == NULL) {
472 return ENOMEM;
475 sockd->funcs = funcs;
476 sockd->private_data = private_data;
478 ret = logging_init(sockd, logging, debug_level, daemon_name);
479 if (ret != 0) {
480 fprintf(stderr,
481 "Failed to initialize logging, logging=%s, debug=%s\n",
482 logging, debug_level);
483 return ret;
486 *out = sockd;
487 return 0;
490 int sock_daemon_add_unix(struct sock_daemon_context *sockd,
491 const char *sockpath,
492 struct sock_socket_funcs *funcs,
493 void *private_data)
495 struct sock_socket *sock;
496 int ret;
498 ret = sock_socket_init(sockd, sockpath, funcs, private_data, &sock);
499 if (ret != 0) {
500 return ret;
504 DLIST_ADD(sockd->socket_list, sock);
505 return 0;
509 * Run socket daemon
512 struct sock_daemon_run_state {
513 struct tevent_context *ev;
514 struct sock_daemon_context *sockd;
515 pid_t pid_watch;
517 int fd;
520 static void sock_daemon_run_started(struct tevent_req *subreq);
521 static void sock_daemon_run_signal_handler(struct tevent_context *ev,
522 struct tevent_signal *se,
523 int signum, int count, void *siginfo,
524 void *private_data);
525 static void sock_daemon_run_reconfigure(struct tevent_req *req);
526 static void sock_daemon_run_shutdown(struct tevent_req *req);
527 static void sock_daemon_run_socket_fail(struct tevent_req *subreq);
528 static void sock_daemon_run_watch_pid(struct tevent_req *subreq);
529 static void sock_daemon_run_wait_done(struct tevent_req *subreq);
531 struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
532 struct tevent_context *ev,
533 struct sock_daemon_context *sockd,
534 const char *pidfile,
535 bool do_fork, bool create_session,
536 pid_t pid_watch)
538 struct tevent_req *req, *subreq;
539 struct sock_daemon_run_state *state;
540 struct tevent_signal *se;
541 struct sock_socket *sock;
542 bool remove_before_use = false;
544 req = tevent_req_create(mem_ctx, &state,
545 struct sock_daemon_run_state);
546 if (req == NULL) {
547 return NULL;
550 become_daemon(do_fork, !create_session, false);
552 if (pidfile != NULL) {
553 int ret = pidfile_context_create(sockd, pidfile,
554 &sockd->pid_ctx);
555 if (ret != 0) {
556 tevent_req_error(req, EEXIST);
557 return tevent_req_post(req, ev);
559 remove_before_use = true;
562 state->ev = ev;
563 state->sockd = sockd;
564 state->pid_watch = pid_watch;
565 state->fd = -1;
567 subreq = tevent_wakeup_send(state, ev,
568 tevent_timeval_current_ofs(0, 0));
569 if (tevent_req_nomem(subreq, req)) {
570 return tevent_req_post(req, ev);
572 tevent_req_set_callback(subreq, sock_daemon_run_started, req);
574 se = tevent_add_signal(ev, state, SIGHUP, 0,
575 sock_daemon_run_signal_handler, req);
576 if (tevent_req_nomem(se, req)) {
577 return tevent_req_post(req, ev);
580 se = tevent_add_signal(ev, state, SIGUSR1, 0,
581 sock_daemon_run_signal_handler, req);
582 if (tevent_req_nomem(se, req)) {
583 return tevent_req_post(req, ev);
586 se = tevent_add_signal(ev, state, SIGINT, 0,
587 sock_daemon_run_signal_handler, req);
588 if (tevent_req_nomem(se, req)) {
589 return tevent_req_post(req, ev);
592 se = tevent_add_signal(ev, state, SIGTERM, 0,
593 sock_daemon_run_signal_handler, req);
594 if (tevent_req_nomem(se, req)) {
595 return tevent_req_post(req, ev);
598 for (sock = sockd->socket_list; sock != NULL; sock = sock->next) {
599 subreq = sock_socket_start_send(state, ev, sock,
600 remove_before_use);
601 if (tevent_req_nomem(subreq, req)) {
602 return tevent_req_post(req, ev);
604 tevent_req_set_callback(subreq, sock_daemon_run_socket_fail,
605 req);
608 if (pid_watch > 1) {
609 subreq = tevent_wakeup_send(state, ev,
610 tevent_timeval_current_ofs(1,0));
611 if (tevent_req_nomem(subreq, req)) {
612 return tevent_req_post(req, ev);
614 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid,
615 req);
618 if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL &&
619 sockd->funcs->wait_recv != NULL) {
620 subreq = sockd->funcs->wait_send(state, ev,
621 sockd->private_data);
622 if (tevent_req_nomem(subreq, req)) {
623 return tevent_req_post(req, ev);
625 tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
626 req);
629 return req;
632 static void sock_daemon_run_started(struct tevent_req *subreq)
634 struct tevent_req *req = tevent_req_callback_data(
635 subreq, struct tevent_req);
636 struct sock_daemon_run_state *state = tevent_req_data(
637 req, struct sock_daemon_run_state);
638 struct sock_daemon_context *sockd = state->sockd;
639 bool status;
641 status = tevent_wakeup_recv(subreq);
642 TALLOC_FREE(subreq);
643 if (! status) {
644 tevent_req_error(req, EIO);
645 return;
648 D_NOTICE("daemon started, pid=%u\n", getpid());
650 if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
651 sockd->funcs->startup(sockd->private_data);
655 static void sock_daemon_run_signal_handler(struct tevent_context *ev,
656 struct tevent_signal *se,
657 int signum, int count, void *siginfo,
658 void *private_data)
660 struct tevent_req *req = talloc_get_type_abort(
661 private_data, struct tevent_req);
663 D_NOTICE("Received signal %d\n", signum);
665 if (signum == SIGHUP || signum == SIGUSR1) {
666 sock_daemon_run_reconfigure(req);
667 return;
670 if (signum == SIGINT || signum == SIGTERM) {
671 sock_daemon_run_shutdown(req);
672 tevent_req_error(req, EINTR);
676 static void sock_daemon_run_reconfigure(struct tevent_req *req)
678 struct sock_daemon_run_state *state = tevent_req_data(
679 req, struct sock_daemon_run_state);
680 struct sock_daemon_context *sockd = state->sockd;
682 if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
683 sockd->funcs->reconfigure(sockd->private_data);
687 static void sock_daemon_run_shutdown(struct tevent_req *req)
689 struct sock_daemon_run_state *state = tevent_req_data(
690 req, struct sock_daemon_run_state);
691 struct sock_daemon_context *sockd = state->sockd;
692 struct sock_socket *sock;
694 D_NOTICE("Shutting down\n");
696 while ((sock = sockd->socket_list) != NULL) {
697 DLIST_REMOVE(sockd->socket_list, sock);
698 TALLOC_FREE(sock);
701 if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) {
702 sockd->funcs->shutdown(sockd->private_data);
705 TALLOC_FREE(sockd->pid_ctx);
708 static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
710 struct tevent_req *req = tevent_req_callback_data(
711 subreq, struct tevent_req);
712 int ret = 0;
713 bool status;
715 status = sock_socket_start_recv(subreq, &ret);
716 TALLOC_FREE(subreq);
717 sock_daemon_run_shutdown(req);
718 if (! status) {
719 tevent_req_error(req, ret);
720 } else {
721 tevent_req_done(req);
725 static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
727 struct tevent_req *req = tevent_req_callback_data(
728 subreq, struct tevent_req);
729 struct sock_daemon_run_state *state = tevent_req_data(
730 req, struct sock_daemon_run_state);
731 int ret;
732 bool status;
734 status = tevent_wakeup_recv(subreq);
735 TALLOC_FREE(subreq);
736 if (! status) {
737 tevent_req_error(req, EIO);
738 return;
741 ret = kill(state->pid_watch, 0);
742 if (ret == -1) {
743 if (errno == ESRCH) {
744 D_ERR("PID %d gone away, exiting\n", state->pid_watch);
745 sock_daemon_run_shutdown(req);
746 tevent_req_error(req, ESRCH);
747 return;
748 } else {
749 D_ERR("Failed to check PID status %d, ret=%d\n",
750 state->pid_watch, errno);
754 subreq = tevent_wakeup_send(state, state->ev,
755 tevent_timeval_current_ofs(5,0));
756 if (tevent_req_nomem(subreq, req)) {
757 return;
759 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
762 static void sock_daemon_run_wait_done(struct tevent_req *subreq)
764 struct tevent_req *req = tevent_req_callback_data(
765 subreq, struct tevent_req);
766 struct sock_daemon_run_state *state = tevent_req_data(
767 req, struct sock_daemon_run_state);
768 struct sock_daemon_context *sockd = state->sockd;
769 int ret;
770 bool status;
772 status = sockd->funcs->wait_recv(subreq, &ret);
773 TALLOC_FREE(subreq);
774 sock_daemon_run_shutdown(req);
775 if (! status) {
776 tevent_req_error(req, ret);
777 } else {
778 tevent_req_done(req);
782 bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
784 int ret;
786 if (tevent_req_is_unix_error(req, &ret)) {
787 if (perr != NULL) {
788 *perr = ret;
790 return false;
793 return true;
796 int sock_daemon_run(struct tevent_context *ev,
797 struct sock_daemon_context *sockd,
798 const char *pidfile,
799 bool do_fork, bool create_session,
800 pid_t pid_watch)
802 struct tevent_req *req;
803 int ret;
804 bool status;
806 req = sock_daemon_run_send(ev, ev, sockd,
807 pidfile, do_fork, create_session, pid_watch);
808 if (req == NULL) {
809 return ENOMEM;
812 tevent_req_poll(req, ev);
814 status = sock_daemon_run_recv(req, &ret);
815 TALLOC_FREE(req);
816 if (! status) {
817 return ret;
820 return 0;