a41a5d5a7ea6a1361756b40db70795310d5f15da
[samba.git] / ctdb / common / sock_daemon.c
1 /*
2    A server based on unix domain socket
3
4    Copyright (C) Amitay Isaacs  2016
5
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.
10
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.
15
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/>.
18 */
19
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
24
25 #include <talloc.h>
26 #include <tevent.h>
27
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
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"
40
41 struct sock_socket {
42         struct sock_socket *prev, *next;
43
44         const char *sockpath;
45         struct sock_socket_funcs *funcs;
46         void *private_data;
47
48         int fd;
49         struct tevent_req *req;
50 };
51
52 struct sock_client {
53         struct sock_client *prev, *next;
54
55         struct tevent_req *req;
56         struct sock_client_context *client_ctx;
57 };
58
59 struct sock_client_context {
60         struct tevent_context *ev;
61         struct sock_socket *sock;
62         int fd;
63         struct comm_context *comm;
64
65         struct sock_client *client;
66 };
67
68 struct sock_daemon_context {
69         struct sock_daemon_funcs *funcs;
70         void *private_data;
71
72         struct pidfile_context *pid_ctx;
73         struct sock_socket *socket_list;
74 };
75
76 /*
77  * Process a single client
78  */
79
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);
86
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)
93 {
94         struct sock_client_context *client_ctx;
95         int ret;
96
97         client_ctx = talloc_zero(mem_ctx, struct sock_client_context);
98         if (client_ctx == NULL) {
99                 return ENOMEM;
100         }
101
102         client_ctx->ev = ev;
103         client_ctx->sock = sock;
104         client_ctx->fd = client_fd;
105         client_ctx->client = client;
106
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;
114         }
115
116         if (sock->funcs->connect != NULL) {
117                 bool status;
118
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;
124                 }
125         }
126
127         talloc_set_destructor(client_ctx, sock_client_context_destructor);
128
129         *result = client_ctx;
130         return 0;
131 }
132
133 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
134                                      void *private_data)
135 {
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;
140
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;
147         }
148         tevent_req_set_callback(subreq, sock_client_read_done, client_ctx);
149 }
150
151 static void sock_client_read_done(struct tevent_req *subreq)
152 {
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;
158
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);
163         }
164 }
165
166 static void sock_client_dead_handler(void *private_data)
167 {
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;
171
172         if (sock->funcs->disconnect != NULL) {
173                 sock->funcs->disconnect(client_ctx, sock->private_data);
174         }
175
176         talloc_free(client_ctx);
177 }
178
179 static int sock_client_context_destructor(
180                                 struct sock_client_context *client_ctx)
181 {
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;
187         }
188
189         return 0;
190 }
191
192 /*
193  * Process a single listening socket
194  */
195
196 static int socket_setup(const char *sockpath, bool remove_before_use)
197 {
198         struct sockaddr_un addr;
199         size_t len;
200         int ret, fd;
201
202         memset(&addr, 0, sizeof(addr));
203         addr.sun_family = AF_UNIX;
204
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;
209         }
210
211         fd = socket(AF_UNIX, SOCK_STREAM, 0);
212         if (fd == -1) {
213                 D_ERR("socket create failed - %s\n", sockpath);
214                 return -1;
215         }
216
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;
222         }
223
224         if (remove_before_use) {
225                 unlink(sockpath);
226         }
227
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;
233         }
234
235         ret = listen(fd, 10);
236         if (ret != 0) {
237                 D_ERR("socket listen failed - %s\n", sockpath);
238                 close(fd);
239                 return -1;
240         }
241
242         D_NOTICE("listening on %s\n", sockpath);
243
244         return fd;
245 }
246
247 static int sock_socket_destructor(struct sock_socket *sock);
248
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)
253 {
254         struct sock_socket *sock;
255
256         if (funcs == NULL) {
257                 return EINVAL;
258         }
259         if (funcs->read_send == NULL || funcs->read_recv == NULL) {
260                 return EINVAL;
261         }
262
263         sock = talloc_zero(mem_ctx, struct sock_socket);
264         if (sock == NULL) {
265                 return ENOMEM;
266         }
267
268         sock->sockpath = sockpath;
269         sock->funcs = funcs;
270         sock->private_data = private_data;
271         sock->fd = -1;
272
273         talloc_set_destructor(sock, sock_socket_destructor);
274
275         *result = sock;
276         return 0;
277 }
278
279 static int sock_socket_destructor(struct sock_socket *sock)
280 {
281         TALLOC_FREE(sock->req);
282
283         if (sock->fd != -1) {
284                 close(sock->fd);
285                 sock->fd = -1;
286         }
287
288         unlink(sock->sockpath);
289         return 0;
290 }
291
292
293 struct sock_socket_start_state {
294         struct tevent_context *ev;
295         struct sock_socket *sock;
296
297         struct sock_client *client_list;
298 };
299
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);
304
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)
309 {
310         struct tevent_req *req, *subreq;
311         struct sock_socket_start_state *state;
312
313         req = tevent_req_create(mem_ctx, &state,
314                                 struct sock_socket_start_state);
315         if (req == NULL) {
316                 return NULL;
317         }
318
319         state->ev = ev;
320         state->sock = sock;
321
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);
326         }
327
328         talloc_set_destructor(state, sock_socket_start_state_destructor);
329
330         subreq = accept_send(state, ev, sock->fd);
331         if (tevent_req_nomem(subreq, req)) {
332                 return tevent_req_post(req, ev);
333         }
334         tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
335
336         sock->req = req;
337
338         return req;
339 }
340
341 static int sock_socket_start_state_destructor(
342                                 struct sock_socket_start_state *state)
343 {
344         struct sock_client *client;
345
346         while ((client = state->client_list) != NULL) {
347                 talloc_free(client);
348         }
349
350         return 0;
351 }
352
353 static void sock_socket_start_new_client(struct tevent_req *subreq)
354 {
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;
361
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");
366         }
367
368         subreq = accept_send(state, state->ev, state->sock->fd);
369         if (tevent_req_nomem(subreq, req)) {
370                 return;
371         }
372         tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
373
374         if (client_fd == -1) {
375                 return;
376         }
377
378         client = talloc_zero(state, struct sock_client);
379         if (tevent_req_nomem(client, req)) {
380                 close(client_fd);
381                 return;
382         }
383
384         client->req = req;
385
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;
391         }
392
393         talloc_set_destructor(client, sock_socket_start_client_destructor);
394         DLIST_ADD(state->client_list, client);
395 }
396
397 static int sock_socket_start_client_destructor(struct sock_client *client)
398 {
399         struct sock_socket_start_state *state = tevent_req_data(
400                 client->req, struct sock_socket_start_state);
401
402         DLIST_REMOVE(state->client_list, client);
403         TALLOC_FREE(client->client_ctx);
404
405         return 0;
406 }
407
408 static bool sock_socket_start_recv(struct tevent_req *req, int *perr)
409 {
410         struct sock_socket_start_state *state = tevent_req_data(
411                 req, struct sock_socket_start_state);
412         int ret;
413
414         state->sock->req = NULL;
415
416         if (tevent_req_is_unix_error(req, &ret)) {
417                 if (perr != NULL) {
418                         *perr = ret;
419                 }
420                 return false;
421         }
422
423         return true;
424 }
425
426 /*
427  * Send message to a client
428  */
429
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)
434 {
435         struct tevent_req *req;
436
437         req = comm_write_send(mem_ctx, ev, client_ctx->comm, buf, buflen);
438
439         return req;
440 }
441
442 bool sock_socket_write_recv(struct tevent_req *req, int *perr)
443 {
444         int ret;
445         bool status;
446
447         status = comm_write_recv(req, &ret);
448         if (! status) {
449                 if (perr != NULL) {
450                         *perr = ret;
451                 }
452         }
453
454         return status;
455 }
456
457 /*
458  * Socket daemon
459  */
460
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)
466 {
467         struct sock_daemon_context *sockd;
468         int ret;
469
470         sockd = talloc_zero(mem_ctx, struct sock_daemon_context);
471         if (sockd == NULL) {
472                 return ENOMEM;
473         }
474
475         sockd->funcs = funcs;
476         sockd->private_data = private_data;
477
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;
484         }
485
486         *out = sockd;
487         return 0;
488 }
489
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)
494 {
495         struct sock_socket *sock;
496         int ret;
497
498         ret = sock_socket_init(sockd, sockpath, funcs, private_data, &sock);
499         if (ret != 0) {
500                 return ret;
501         }
502
503
504         DLIST_ADD(sockd->socket_list, sock);
505         return 0;
506 }
507
508 /*
509  * Run socket daemon
510  */
511
512 struct sock_daemon_run_state {
513         struct tevent_context *ev;
514         struct sock_daemon_context *sockd;
515         pid_t pid_watch;
516
517         int fd;
518 };
519
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);
530
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)
537 {
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;
543
544         req = tevent_req_create(mem_ctx, &state,
545                                 struct sock_daemon_run_state);
546         if (req == NULL) {
547                 return NULL;
548         }
549
550         become_daemon(do_fork, !create_session, false);
551
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);
558                 }
559                 remove_before_use = true;
560         }
561
562         state->ev = ev;
563         state->sockd = sockd;
564         state->pid_watch = pid_watch;
565         state->fd  = -1;
566
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);
571         }
572         tevent_req_set_callback(subreq, sock_daemon_run_started, req);
573
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);
578         }
579
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);
584         }
585
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);
590         }
591
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);
596         }
597
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);
603                 }
604                 tevent_req_set_callback(subreq, sock_daemon_run_socket_fail,
605                                         req);
606         }
607
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);
613                 }
614                 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid,
615                                         req);
616         }
617
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);
624                 }
625                 tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
626                                         req);
627         }
628
629         return req;
630 }
631
632 static void sock_daemon_run_started(struct tevent_req *subreq)
633 {
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;
640
641         status = tevent_wakeup_recv(subreq);
642         TALLOC_FREE(subreq);
643         if (! status) {
644                 tevent_req_error(req, EIO);
645                 return;
646         }
647
648         D_NOTICE("daemon started, pid=%u\n", getpid());
649
650         if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
651                 sockd->funcs->startup(sockd->private_data);
652         }
653 }
654
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)
659 {
660         struct tevent_req *req = talloc_get_type_abort(
661                 private_data, struct tevent_req);
662
663         D_NOTICE("Received signal %d\n", signum);
664
665         if (signum == SIGHUP || signum == SIGUSR1) {
666                 sock_daemon_run_reconfigure(req);
667                 return;
668         }
669
670         if (signum == SIGINT || signum == SIGTERM) {
671                 sock_daemon_run_shutdown(req);
672                 tevent_req_error(req, EINTR);
673         }
674 }
675
676 static void sock_daemon_run_reconfigure(struct tevent_req *req)
677 {
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;
681
682         if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
683                 sockd->funcs->reconfigure(sockd->private_data);
684         }
685 }
686
687 static void sock_daemon_run_shutdown(struct tevent_req *req)
688 {
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;
693
694         D_NOTICE("Shutting down\n");
695
696         while ((sock = sockd->socket_list) != NULL) {
697                 DLIST_REMOVE(sockd->socket_list, sock);
698                 TALLOC_FREE(sock);
699         }
700
701         if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) {
702                 sockd->funcs->shutdown(sockd->private_data);
703         }
704
705         TALLOC_FREE(sockd->pid_ctx);
706 }
707
708 static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
709 {
710         struct tevent_req *req = tevent_req_callback_data(
711                 subreq, struct tevent_req);
712         int ret = 0;
713         bool status;
714
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);
722         }
723 }
724
725 static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
726 {
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;
733
734         status = tevent_wakeup_recv(subreq);
735         TALLOC_FREE(subreq);
736         if (! status) {
737                 tevent_req_error(req, EIO);
738                 return;
739         }
740
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);
751                 }
752         }
753
754         subreq = tevent_wakeup_send(state, state->ev,
755                                     tevent_timeval_current_ofs(5,0));
756         if (tevent_req_nomem(subreq, req)) {
757                 return;
758         }
759         tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
760 }
761
762 static void sock_daemon_run_wait_done(struct tevent_req *subreq)
763 {
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;
771
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);
779         }
780 }
781
782 bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
783 {
784         int ret;
785
786         if (tevent_req_is_unix_error(req, &ret)) {
787                 if (perr != NULL) {
788                         *perr = ret;
789                 }
790                 return false;
791         }
792
793         return true;
794 }
795
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)
801 {
802         struct tevent_req *req;
803         int ret;
804         bool status;
805
806         req = sock_daemon_run_send(ev, ev, sockd,
807                                    pidfile, do_fork, create_session, pid_watch);
808         if (req == NULL) {
809                 return ENOMEM;
810         }
811
812         tevent_req_poll(req, ev);
813
814         status = sock_daemon_run_recv(req, &ret);
815         TALLOC_FREE(req);
816         if (! status) {
817                 return ret;
818         }
819
820         return 0;
821 }