bba0df26a0a8797536a788e178e4c6b4262de561
[vlendec/samba-autobuild/.git] / ctdb / tests / src / sock_daemon_test.c
1 /*
2    sock daemon tests
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 <assert.h>
26
27 #include "common/logging.c"
28 #include "common/pkt_read.c"
29 #include "common/pkt_write.c"
30 #include "common/comm.c"
31 #include "common/pidfile.c"
32 #include "common/sock_daemon.c"
33 #include "common/sock_io.c"
34
35 struct dummy_wait_state {
36 };
37
38 static struct tevent_req *dummy_wait_send(TALLOC_CTX *mem_ctx,
39                                           struct tevent_context *ev,
40                                           void *private_data)
41 {
42         struct tevent_req *req;
43         struct dummy_wait_state *state;
44         const char *sockpath = (const char *)private_data;
45         struct stat st;
46         int ret;
47
48         ret = stat(sockpath, &st);
49         assert(ret == 0);
50         assert(S_ISSOCK(st.st_mode));
51
52         req = tevent_req_create(mem_ctx, &state, struct dummy_wait_state);
53         if (req == NULL) {
54                 return NULL;
55         }
56
57         tevent_req_done(req);
58         return tevent_req_post(req, ev);
59 }
60
61 static bool dummy_wait_recv(struct tevent_req *req, int *perr)
62 {
63         return true;
64 }
65
66 static struct sock_daemon_funcs test1_funcs = {
67         .wait_send = dummy_wait_send,
68         .wait_recv = dummy_wait_recv,
69 };
70
71 static struct tevent_req *dummy_read_send(TALLOC_CTX *mem_ctx,
72                                           struct tevent_context *ev,
73                                           struct sock_client_context *client,
74                                           uint8_t *buf, size_t buflen,
75                                           void *private_data)
76 {
77         return NULL;
78 }
79
80 static bool dummy_read_recv(struct tevent_req *req, int *perr)
81 {
82         if (perr != NULL) {
83                 *perr = EINVAL;
84         }
85         return false;
86 }
87
88 static struct sock_socket_funcs dummy_socket_funcs = {
89         .read_send = dummy_read_send,
90         .read_recv = dummy_read_recv,
91 };
92
93 /*
94  * test1
95  *
96  * Check setup without actually running daemon
97  */
98
99 static void test1(TALLOC_CTX *mem_ctx, const char *pidfile,
100                   const char *sockpath)
101 {
102         struct tevent_context *ev;
103         struct sock_daemon_context *sockd;
104         struct stat st;
105         int ret;
106
107         ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE",
108                                 &test1_funcs, discard_const(sockpath), &sockd);
109         assert(ret == 0);
110         assert(sockd != NULL);
111
112         ret = stat(pidfile, &st);
113         assert(ret == -1);
114
115         ret = sock_daemon_add_unix(sockd, sockpath, &dummy_socket_funcs, NULL);
116         assert(ret == 0);
117
118         ret = stat(sockpath, &st);
119         assert(ret == -1);
120
121         ev = tevent_context_init(mem_ctx);
122         assert(ev != NULL);
123
124         ret = sock_daemon_run(ev, sockd, NULL, false, false, -1);
125         assert(ret == 0);
126
127         talloc_free(mem_ctx);
128 }
129
130 /*
131  * test2
132  *
133  * Start daemon, check PID file, sock daemon functions, termination,
134  * exit code
135  */
136
137 static void test2_startup(void *private_data)
138 {
139         int fd = *(int *)private_data;
140         int ret = 1;
141         ssize_t nwritten;
142
143         nwritten = write(fd, &ret, sizeof(ret));
144         assert(nwritten == sizeof(ret));
145 }
146
147 static void test2_reconfigure(void *private_data)
148 {
149         int fd = *(int *)private_data;
150         int ret = 2;
151         ssize_t nwritten;
152
153         nwritten = write(fd, &ret, sizeof(ret));
154         assert(nwritten == sizeof(ret));
155 }
156
157 static void test2_shutdown(void *private_data)
158 {
159         int fd = *(int *)private_data;
160         int ret = 3;
161         ssize_t nwritten;
162
163         nwritten = write(fd, &ret, sizeof(ret));
164         assert(nwritten == sizeof(ret));
165 }
166
167 static struct sock_daemon_funcs test2_funcs = {
168         .startup = test2_startup,
169         .reconfigure = test2_reconfigure,
170         .shutdown = test2_shutdown,
171 };
172
173 static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
174                   const char *sockpath)
175 {
176         struct stat st;
177         int fd[2];
178         pid_t pid, pid2;
179         int ret;
180         ssize_t n;
181         int pidfile_fd;
182         char pidstr[20] = { 0 };
183
184         ret = pipe(fd);
185         assert(ret == 0);
186
187         pid = fork();
188         assert(pid != -1);
189
190         if (pid == 0) {
191                 struct tevent_context *ev;
192                 struct sock_daemon_context *sockd;
193
194                 close(fd[0]);
195
196                 ev = tevent_context_init(mem_ctx);
197                 assert(ev != NULL);
198
199                 ret = sock_daemon_setup(mem_ctx, "test2", "file:", "NOTICE",
200                                         &test2_funcs, &fd[1], &sockd);
201                 assert(ret == 0);
202
203                 ret = sock_daemon_add_unix(sockd, sockpath,
204                                            &dummy_socket_funcs, NULL);
205                 assert(ret == 0);
206
207                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
208                 assert(ret == EINTR);
209
210                 exit(0);
211         }
212
213         close(fd[1]);
214
215         n = read(fd[0], &ret, sizeof(ret));
216         assert(n == sizeof(ret));
217         assert(ret == 1);
218
219         ret = stat(pidfile, &st);
220         assert(ret == 0);
221         assert(S_ISREG(st.st_mode));
222
223         pidfile_fd = open(pidfile, O_RDONLY, 0644);
224         assert(pidfile_fd != -1);
225         n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
226         assert(n != -1);
227         pid2 = (pid_t)atoi(pidstr);
228         assert(pid == pid2);
229
230         ret = kill(pid, SIGHUP);
231         assert(ret == 0);
232
233         n = read(fd[0], &ret, sizeof(ret));
234         assert(n == sizeof(ret));
235         assert(ret == 2);
236
237         ret = kill(pid, SIGUSR1);
238         assert(ret == 0);
239
240         n = read(fd[0], &ret, sizeof(ret));
241         assert(n == sizeof(ret));
242         assert(ret == 2);
243
244         ret = kill(pid, SIGTERM);
245         assert(ret == 0);
246
247         n = read(fd[0], &ret, sizeof(ret));
248         assert(n == sizeof(ret));
249         assert(ret == 3);
250
251         pid2 = waitpid(pid, &ret, 0);
252         assert(pid2 == pid);
253         assert(WEXITSTATUS(ret) == 0);
254
255         close(fd[0]);
256
257         ret = stat(pidfile, &st);
258         assert(ret == -1);
259
260         ret = stat(sockpath, &st);
261         assert(ret == -1);
262 }
263
264 /*
265  * test3
266  *
267  * Start daemon, test watching of (parent) PID
268  */
269
270 static void test3(TALLOC_CTX *mem_ctx, const char *pidfile,
271                   const char *sockpath)
272 {
273         struct stat st;
274         pid_t pid_watch, pid, pid2;
275         int ret;
276
277         pid_watch = fork();
278         assert(pid_watch != -1);
279
280         if (pid_watch == 0) {
281                 sleep(10);
282                 exit(0);
283         }
284
285         pid = fork();
286         assert(pid != -1);
287
288         if (pid == 0) {
289                 struct tevent_context *ev;
290                 struct sock_daemon_context *sockd;
291
292                 ev = tevent_context_init(mem_ctx);
293                 assert(ev != NULL);
294
295                 ret = sock_daemon_setup(mem_ctx, "test3", "file:", "NOTICE",
296                                         NULL, NULL, &sockd);
297                 assert(ret == 0);
298
299                 ret = sock_daemon_add_unix(sockd, sockpath,
300                                            &dummy_socket_funcs, NULL);
301                 assert(ret == 0);
302
303                 ret = sock_daemon_run(ev, sockd, NULL, false, false, pid_watch);
304                 assert(ret == ESRCH);
305
306                 exit(0);
307         }
308
309         pid2 = waitpid(pid_watch, &ret, 0);
310         assert(pid2 == pid_watch);
311         assert(WEXITSTATUS(ret) == 0);
312
313         pid2 = waitpid(pid, &ret, 0);
314         assert(pid2 == pid);
315         assert(WEXITSTATUS(ret) == 0);
316
317         ret = stat(pidfile, &st);
318         assert(ret == -1);
319
320         ret = stat(sockpath, &st);
321         assert(ret == -1);
322 }
323
324 /*
325  * test4
326  *
327  * Start daemon, test termination via wait_send function
328  */
329
330 struct test4_wait_state {
331 };
332
333 static void test4_wait_done(struct tevent_req *subreq);
334
335 static struct tevent_req *test4_wait_send(TALLOC_CTX *mem_ctx,
336                                           struct tevent_context *ev,
337                                           void *private_data)
338 {
339         struct tevent_req *req, *subreq;
340         struct test4_wait_state *state;
341
342         req = tevent_req_create(mem_ctx, &state, struct test4_wait_state);
343         if (req == NULL) {
344                 return NULL;
345         }
346
347         subreq = tevent_wakeup_send(state, ev,
348                                     tevent_timeval_current_ofs(10,0));
349         if (tevent_req_nomem(subreq, req)) {
350                 return tevent_req_post(req, ev);
351         }
352         tevent_req_set_callback(subreq, test4_wait_done, req);
353
354         return req;
355 }
356
357 static void test4_wait_done(struct tevent_req *subreq)
358 {
359         struct tevent_req *req = tevent_req_callback_data(
360                 subreq, struct tevent_req);
361         bool status;
362
363         status = tevent_wakeup_recv(subreq);
364         TALLOC_FREE(subreq);
365
366         if (! status) {
367                 tevent_req_error(req, EIO);
368         } else {
369                 tevent_req_done(req);
370         }
371 }
372
373 static bool test4_wait_recv(struct tevent_req *req, int *perr)
374 {
375         int ret;
376
377         if (tevent_req_is_unix_error(req, &ret)) {
378                 if (perr != NULL) {
379                         *perr = ret;
380                 }
381                 return false;
382         }
383
384         return true;
385 }
386
387 static struct sock_daemon_funcs test4_funcs = {
388         .wait_send = test4_wait_send,
389         .wait_recv = test4_wait_recv,
390 };
391
392 static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
393                   const char *sockpath)
394 {
395         struct stat st;
396         pid_t pid, pid2;
397         int ret;
398
399         pid = fork();
400         assert(pid != -1);
401
402         if (pid == 0) {
403                 struct tevent_context *ev;
404                 struct sock_daemon_context *sockd;
405
406                 ev = tevent_context_init(mem_ctx);
407                 assert(ev != NULL);
408
409                 ret = sock_daemon_setup(mem_ctx, "test4", "file:", "NOTICE",
410                                         &test4_funcs, NULL, &sockd);
411                 assert(ret == 0);
412
413                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
414                 assert(ret == 0);
415
416                 exit(0);
417         }
418
419         pid2 = waitpid(pid, &ret, 0);
420         assert(pid2 == pid);
421         assert(WEXITSTATUS(ret) == 0);
422
423         ret = stat(pidfile, &st);
424         assert(ret == -1);
425
426         ret = stat(sockpath, &st);
427         assert(ret == -1);
428 }
429
430 /*
431  * test5
432  *
433  * Start daemon, multiple client connects, requests, disconnects
434  */
435
436 #define TEST5_MAX_CLIENTS       10
437
438 struct test5_pkt {
439         uint32_t len;
440         int data;
441 };
442
443 struct test5_client_state {
444         int id;
445         int fd;
446         bool done;
447 };
448
449 static void test5_client_callback(uint8_t *buf, size_t buflen,
450                                   void *private_data)
451 {
452         struct test5_client_state *state =
453                 (struct test5_client_state *)private_data;
454         struct test5_pkt *pkt;
455         ssize_t n;
456         int ret;
457
458         if (buf == NULL) {
459                 assert(buflen == 0);
460
461                 ret = 0;
462         } else {
463                 assert(buflen == sizeof(struct test5_pkt));
464                 pkt = (struct test5_pkt *)buf;
465                 assert(pkt->len == sizeof(struct test5_pkt));
466
467                 ret = pkt->data;
468         }
469
470         assert(state->fd != -1);
471
472         n = write(state->fd, (void *)&ret, sizeof(int));
473         assert(n == sizeof(int));
474
475         state->done = true;
476 }
477
478 static int test5_client(const char *sockpath, int id)
479 {
480         pid_t pid;
481         int fd[2];
482         int ret;
483         ssize_t n;
484
485         ret = pipe(fd);
486         assert(ret == 0);
487
488         pid = fork();
489         assert(pid != -1);
490
491         if (pid == 0) {
492                 struct tevent_context *ev;
493                 struct test5_client_state state;
494                 struct sock_queue *queue;
495                 struct test5_pkt pkt;
496                 int conn;
497
498                 close(fd[0]);
499
500                 ev = tevent_context_init(NULL);
501                 assert(ev != NULL);
502
503                 conn = sock_connect(sockpath);
504                 assert(conn != -1);
505
506                 state.id = id;
507                 state.fd = fd[1];
508                 state.done = false;
509
510                 queue = sock_queue_setup(ev, ev, conn,
511                                          test5_client_callback, &state);
512                 assert(queue != NULL);
513
514                 pkt.len = 8;
515                 pkt.data = 0xbaba;
516
517                 ret = sock_queue_write(queue, (uint8_t *)&pkt,
518                                        sizeof(struct test5_pkt));
519                 assert(ret == 0);
520
521                 while (! state.done) {
522                         tevent_loop_once(ev);
523                 }
524
525                 close(fd[0]);
526                 state.fd = -1;
527
528                 sleep(10);
529                 exit(0);
530         }
531
532         close(fd[1]);
533
534         ret = 0;
535         n = read(fd[0], &ret, sizeof(ret));
536         if (n == 0) {
537                 fprintf(stderr, "client id %d read 0 bytes\n", id);
538         }
539         assert(n == 0 || n == sizeof(ret));
540
541         close(fd[0]);
542
543         return ret;
544 }
545
546 struct test5_server_state {
547         int num_clients;
548 };
549
550 static bool test5_connect(struct sock_client_context *client,
551                           void *private_data)
552 {
553         struct test5_server_state *state =
554                 (struct test5_server_state *)private_data;
555
556         if (state->num_clients == TEST5_MAX_CLIENTS) {
557                 return false;
558         }
559
560         state->num_clients += 1;
561         assert(state->num_clients <= TEST5_MAX_CLIENTS);
562         return true;
563 }
564
565 static void test5_disconnect(struct sock_client_context *client,
566                              void *private_data)
567 {
568         struct test5_server_state *state =
569                 (struct test5_server_state *)private_data;
570
571         state->num_clients -= 1;
572         assert(state->num_clients >= 0);
573 }
574
575 struct test5_read_state {
576         struct test5_pkt reply;
577 };
578
579 static void test5_read_done(struct tevent_req *subreq);
580
581 static struct tevent_req *test5_read_send(TALLOC_CTX *mem_ctx,
582                                           struct tevent_context *ev,
583                                           struct sock_client_context *client,
584                                           uint8_t *buf, size_t buflen,
585                                           void *private_data)
586 {
587         struct test5_server_state *server_state =
588                 (struct test5_server_state *)private_data;
589         struct tevent_req *req, *subreq;
590         struct test5_read_state *state;
591         struct test5_pkt *pkt;
592
593         req = tevent_req_create(mem_ctx, &state, struct test5_read_state);
594         assert(req != NULL);
595
596         assert(buflen == sizeof(struct test5_pkt));
597
598         pkt = (struct test5_pkt *)buf;
599         assert(pkt->data == 0xbaba);
600
601         state->reply.len = sizeof(struct test5_pkt);
602         state->reply.data = server_state->num_clients;
603
604         subreq = sock_socket_write_send(state, ev, client,
605                                         (uint8_t *)&state->reply,
606                                         state->reply.len);
607         assert(subreq != NULL);
608
609         tevent_req_set_callback(subreq, test5_read_done, req);
610
611         return req;
612 }
613
614 static void test5_read_done(struct tevent_req *subreq)
615 {
616         struct tevent_req *req = tevent_req_callback_data(
617                 subreq, struct tevent_req);
618         int ret;
619         bool status;
620
621         status = sock_socket_write_recv(subreq, &ret);
622         TALLOC_FREE(subreq);
623         if (! status) {
624                 tevent_req_error(req, ret);
625                 return;
626         }
627
628         tevent_req_done(req);
629 }
630
631 static bool test5_read_recv(struct tevent_req *req, int *perr)
632 {
633         int ret;
634
635         if (tevent_req_is_unix_error(req, &ret)) {
636                 if (perr != NULL) {
637                         *perr = ret;
638                 }
639                 return false;
640         }
641
642         return true;
643 }
644
645 static struct sock_socket_funcs test5_client_funcs = {
646         .connect = test5_connect,
647         .disconnect = test5_disconnect,
648         .read_send = test5_read_send,
649         .read_recv = test5_read_recv,
650 };
651
652 static void test5_startup(void *private_data)
653 {
654         int fd = *(int *)private_data;
655         int ret = 1;
656         ssize_t nwritten;
657
658         nwritten = write(fd, &ret, sizeof(ret));
659         assert(nwritten == sizeof(ret));
660         close(fd);
661 }
662
663 static struct sock_daemon_funcs test5_funcs = {
664         .startup = test5_startup,
665 };
666
667 static void test5(TALLOC_CTX *mem_ctx, const char *pidfile,
668                   const char *sockpath)
669 {
670         pid_t pid_server, pid;
671         int fd[2], ret, i;
672         ssize_t n;
673
674         pid = getpid();
675
676         ret = pipe(fd);
677         assert(ret == 0);
678
679         pid_server = fork();
680         assert(pid_server != -1);
681
682         if (pid_server == 0) {
683                 struct tevent_context *ev;
684                 struct sock_daemon_context *sockd;
685                 struct test5_server_state state;
686
687                 close(fd[0]);
688
689                 ev = tevent_context_init(mem_ctx);
690                 assert(ev != NULL);
691
692                 ret = sock_daemon_setup(mem_ctx, "test5", "file:", "NOTICE",
693                                         &test5_funcs, &fd[1], &sockd);
694                 assert(ret == 0);
695
696                 state.num_clients = 0;
697
698                 ret = sock_daemon_add_unix(sockd, sockpath,
699                                            &test5_client_funcs, &state);
700                 assert(ret == 0);
701
702                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
703                 assert(ret == EINTR);
704
705                 exit(0);
706         }
707
708         close(fd[1]);
709
710         n = read(fd[0], &ret, sizeof(ret));
711         assert(n == sizeof(ret));
712         assert(ret == 1);
713
714         close(fd[0]);
715
716         for (i=0; i<100; i++) {
717                 ret = test5_client(sockpath, i);
718                 if (i < TEST5_MAX_CLIENTS) {
719                         assert(ret == i+1);
720                 } else {
721                         assert(ret == 0);
722                 }
723         }
724
725         for (i=0; i<100; i++) {
726                 pid = wait(&ret);
727                 assert(pid != -1);
728         }
729
730         ret = kill(pid_server, SIGTERM);
731         assert(ret == 0);
732 }
733
734 /*
735  * test6
736  *
737  * Start daemon, test client connects, requests, replies, disconnects
738  */
739
740 struct test6_pkt {
741         uint32_t len;
742         uint32_t data;
743 };
744
745 struct test6_client_state {
746         bool done;
747 };
748
749 static void test6_client_callback(uint8_t *buf, size_t buflen,
750                                   void *private_data)
751 {
752         struct test6_client_state *state =
753                 (struct test6_client_state *)private_data;
754         struct test6_pkt *pkt;
755
756         assert(buflen == sizeof(struct test6_pkt));
757         pkt = (struct test6_pkt *)buf;
758         assert(pkt->len == sizeof(struct test6_pkt));
759         assert(pkt->data == 0xffeeddcc);
760
761         state->done = true;
762 }
763
764 static void test6_client(const char *sockpath)
765 {
766         struct tevent_context *ev;
767         struct test6_client_state state;
768         struct sock_queue *queue;
769         struct test6_pkt pkt;
770         int conn, ret;
771
772         ev = tevent_context_init(NULL);
773         assert(ev != NULL);
774
775         conn = sock_connect(sockpath);
776         assert(conn != -1);
777
778         state.done = false;
779
780         queue = sock_queue_setup(ev, ev, conn,
781                                  test6_client_callback, &state);
782         assert(queue != NULL);
783
784         pkt.len = 8;
785         pkt.data = 0xaabbccdd;
786
787         ret = sock_queue_write(queue, (uint8_t *)&pkt,
788                                sizeof(struct test6_pkt));
789         assert(ret == 0);
790
791         while (! state.done) {
792                 tevent_loop_once(ev);
793         }
794
795         talloc_free(ev);
796 }
797
798 struct test6_server_state {
799         struct sock_daemon_context *sockd;
800         int fd, done;
801 };
802
803 struct test6_read_state {
804         struct test6_server_state *server_state;
805         struct test6_pkt reply;
806 };
807
808 static void test6_read_done(struct tevent_req *subreq);
809
810 static struct tevent_req *test6_read_send(TALLOC_CTX *mem_ctx,
811                                           struct tevent_context *ev,
812                                           struct sock_client_context *client,
813                                           uint8_t *buf, size_t buflen,
814                                           void *private_data)
815 {
816         struct test6_server_state *server_state =
817                 (struct test6_server_state *)private_data;
818         struct tevent_req *req, *subreq;
819         struct test6_read_state *state;
820         struct test6_pkt *pkt;
821
822         req = tevent_req_create(mem_ctx, &state, struct test6_read_state);
823         assert(req != NULL);
824
825         state->server_state = server_state;
826
827         assert(buflen == sizeof(struct test6_pkt));
828
829         pkt = (struct test6_pkt *)buf;
830         assert(pkt->data == 0xaabbccdd);
831
832         state->reply.len = sizeof(struct test6_pkt);
833         state->reply.data = 0xffeeddcc;
834
835         subreq = sock_socket_write_send(state, ev, client,
836                                         (uint8_t *)&state->reply,
837                                         state->reply.len);
838         assert(subreq != NULL);
839
840         tevent_req_set_callback(subreq, test6_read_done, req);
841
842         return req;
843 }
844
845 static void test6_read_done(struct tevent_req *subreq)
846 {
847         struct tevent_req *req = tevent_req_callback_data(
848                 subreq, struct tevent_req);
849         struct test6_read_state *state = tevent_req_data(
850                 req, struct test6_read_state);
851         int ret;
852         bool status;
853
854         status = sock_socket_write_recv(subreq, &ret);
855         TALLOC_FREE(subreq);
856         if (! status) {
857                 tevent_req_error(req, ret);
858                 return;
859         }
860
861         state->server_state->done = 1;
862         tevent_req_done(req);
863 }
864
865 static bool test6_read_recv(struct tevent_req *req, int *perr)
866 {
867         int ret;
868
869         if (tevent_req_is_unix_error(req, &ret)) {
870                 if (perr != NULL) {
871                         *perr = ret;
872                 }
873                 return false;
874         }
875
876         return true;
877 }
878
879 static struct sock_socket_funcs test6_client_funcs = {
880         .read_send = test6_read_send,
881         .read_recv = test6_read_recv,
882 };
883
884 static void test6_startup(void *private_data)
885 {
886         struct test6_server_state *server_state =
887                 (struct test6_server_state *)private_data;
888         int ret = 1;
889         ssize_t nwritten;
890
891         nwritten = write(server_state->fd, &ret, sizeof(ret));
892         assert(nwritten == sizeof(ret));
893         close(server_state->fd);
894         server_state->fd = -1;
895 }
896
897 struct test6_wait_state {
898         struct test6_server_state *server_state;
899 };
900
901 static void test6_wait_done(struct tevent_req *subreq);
902
903 static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
904                                           struct tevent_context *ev,
905                                           void *private_data)
906 {
907         struct tevent_req *req, *subreq;
908         struct test6_wait_state *state;
909
910         req = tevent_req_create(mem_ctx, &state, struct test6_wait_state);
911         if (req == NULL) {
912                 return NULL;
913         }
914
915         state->server_state = (struct test6_server_state *)private_data;
916
917         subreq = tevent_wakeup_send(state, ev,
918                                     tevent_timeval_current_ofs(10,0));
919         if (tevent_req_nomem(subreq, req)) {
920                 return tevent_req_post(req, ev);
921         }
922         tevent_req_set_callback(subreq, test6_wait_done, req);
923
924         return req;
925 }
926
927 static void test6_wait_done(struct tevent_req *subreq)
928 {
929         struct tevent_req *req = tevent_req_callback_data(
930                 subreq, struct tevent_req);
931         struct test6_wait_state *state = tevent_req_data(
932                 req, struct test6_wait_state);
933         bool status;
934
935         status = tevent_wakeup_recv(subreq);
936         TALLOC_FREE(subreq);
937         if (! status) {
938                 tevent_req_error(req, EIO);
939                 return;
940         }
941
942         if (state->server_state->done == 0) {
943                 tevent_req_error(req, EIO);
944                 return;
945         }
946
947         tevent_req_done(req);
948 }
949
950 static bool test6_wait_recv(struct tevent_req *req, int *perr)
951 {
952         int ret;
953
954         if (tevent_req_is_unix_error(req, &ret)) {
955                 if (perr != NULL) {
956                         *perr = ret;
957                 }
958                 return false;
959         }
960
961         return true;
962 }
963
964 static struct sock_daemon_funcs test6_funcs = {
965         .startup = test6_startup,
966         .wait_send = test6_wait_send,
967         .wait_recv = test6_wait_recv,
968 };
969
970 static void test6(TALLOC_CTX *mem_ctx, const char *pidfile,
971                   const char *sockpath)
972 {
973         pid_t pid_server, pid;
974         int fd[2], ret;
975         ssize_t n;
976
977         pid = getpid();
978
979         ret = pipe(fd);
980         assert(ret == 0);
981
982         pid_server = fork();
983         assert(pid_server != -1);
984
985         if (pid_server == 0) {
986                 struct tevent_context *ev;
987                 struct sock_daemon_context *sockd;
988                 struct test6_server_state server_state = { 0 };
989
990                 close(fd[0]);
991
992                 ev = tevent_context_init(mem_ctx);
993                 assert(ev != NULL);
994
995                 server_state.fd = fd[1];
996
997                 ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE",
998                                         &test6_funcs, &server_state,
999                                         &sockd);
1000                 assert(ret == 0);
1001
1002                 server_state.sockd = sockd;
1003                 server_state.done = 0;
1004
1005                 ret = sock_daemon_add_unix(sockd, sockpath,
1006                                            &test6_client_funcs, &server_state);
1007                 assert(ret == 0);
1008
1009                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, pid);
1010                 assert(ret == 0);
1011
1012                 exit(0);
1013         }
1014
1015         close(fd[1]);
1016
1017         n = read(fd[0], &ret, sizeof(ret));
1018         assert(n == sizeof(ret));
1019         assert(ret == 1);
1020
1021         close(fd[0]);
1022
1023         test6_client(sockpath);
1024
1025         pid = wait(&ret);
1026         assert(pid != -1);
1027 }
1028
1029 /*
1030  * test7
1031  *
1032  * Start daemon twice, confirm PID file contention
1033  */
1034
1035 static void test7(TALLOC_CTX *mem_ctx, const char *pidfile,
1036                   const char *sockpath)
1037 {
1038         struct stat st;
1039         int fd[2];
1040         pid_t pid, pid2;
1041         int ret;
1042         struct tevent_context *ev;
1043         struct sock_daemon_context *sockd;
1044         ssize_t n;
1045
1046         ret = pipe(fd);
1047         assert(ret == 0);
1048
1049         pid = fork();
1050         assert(pid != -1);
1051
1052         if (pid == 0) {
1053                 close(fd[0]);
1054
1055                 ev = tevent_context_init(mem_ctx);
1056                 assert(ev != NULL);
1057
1058                 /* Reuse test2 funcs for the startup synchronisation */
1059                 ret = sock_daemon_setup(mem_ctx, "test7", "file:", "NOTICE",
1060                                         &test2_funcs, &fd[1], &sockd);
1061                 assert(ret == 0);
1062
1063                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1064                 assert(ret == EINTR);
1065
1066                 exit(0);
1067         }
1068
1069         close(fd[1]);
1070
1071         n = read(fd[0], &ret, sizeof(ret));
1072         assert(n == sizeof(ret));
1073         assert(ret == 1);
1074
1075         ret = stat(pidfile, &st);
1076         assert(ret == 0);
1077         assert(S_ISREG(st.st_mode));
1078
1079         ev = tevent_context_init(mem_ctx);
1080         assert(ev != NULL);
1081
1082         /* Reuse test2 funcs for the startup synchronisation */
1083         ret = sock_daemon_setup(mem_ctx, "test7-parent", "file:", "NOTICE",
1084                                 &test2_funcs, &fd[1], &sockd);
1085         assert(ret == 0);
1086
1087         ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1088         assert(ret == EEXIST);
1089
1090         ret = kill(pid, SIGTERM);
1091         assert(ret == 0);
1092
1093         n = read(fd[0], &ret, sizeof(ret));
1094         assert(n == sizeof(ret));
1095         assert(ret == 3);
1096
1097         pid2 = waitpid(pid, &ret, 0);
1098         assert(pid2 == pid);
1099         assert(WEXITSTATUS(ret) == 0);
1100
1101         close(fd[0]);
1102 }
1103
1104 /*
1105  * test8
1106  *
1107  * Start daemon, confirm that create_session argument works as expected
1108  */
1109
1110 static void test8(TALLOC_CTX *mem_ctx, const char *pidfile,
1111                   const char *sockpath)
1112 {
1113         int fd[2];
1114         pid_t pid, pid2, sid;
1115         int ret;
1116         struct tevent_context *ev;
1117         struct sock_daemon_context *sockd;
1118         ssize_t n;
1119
1120         ret = pipe(fd);
1121         assert(ret == 0);
1122
1123         pid = fork();
1124         assert(pid != -1);
1125
1126         if (pid == 0) {
1127                 close(fd[0]);
1128
1129                 ev = tevent_context_init(mem_ctx);
1130                 assert(ev != NULL);
1131
1132                 /* Reuse test2 funcs for the startup synchronisation */
1133                 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1134                                         &test2_funcs, &fd[1], &sockd);
1135                 assert(ret == 0);
1136
1137                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1138                 assert(ret == EINTR);
1139
1140                 exit(0);
1141         }
1142
1143         close(fd[1]);
1144
1145         n = read(fd[0], &ret, sizeof(ret));
1146         assert(n == sizeof(ret));
1147         assert(ret == 1);
1148
1149         /* create_session false above, so pid != sid */
1150         sid = getsid(pid);
1151         assert(pid != sid);
1152
1153         ret = kill(pid, SIGTERM);
1154         assert(ret == 0);
1155
1156         n = read(fd[0], &ret, sizeof(ret));
1157         assert(n == sizeof(ret));
1158         assert(ret == 3);
1159
1160         pid2 = waitpid(pid, &ret, 0);
1161         assert(pid2 == pid);
1162         assert(WEXITSTATUS(ret) == 0);
1163
1164         close(fd[0]);
1165
1166         ret = pipe(fd);
1167         assert(ret == 0);
1168
1169         pid = fork();
1170         assert(pid != -1);
1171
1172         if (pid == 0) {
1173                 close(fd[0]);
1174
1175                 ev = tevent_context_init(mem_ctx);
1176                 assert(ev != NULL);
1177
1178                 /* Reuse test2 funcs for the startup synchronisation */
1179                 ret = sock_daemon_setup(mem_ctx, "test8", "file:", "NOTICE",
1180                                         &test2_funcs, &fd[1], &sockd);
1181                 assert(ret == 0);
1182
1183                 ret = sock_daemon_run(ev, sockd, pidfile, false, true, -1);
1184                 assert(ret == EINTR);
1185
1186                 exit(0);
1187         }
1188
1189         close(fd[1]);
1190
1191         n = read(fd[0], &ret, sizeof(ret));
1192         assert(n == sizeof(ret));
1193         assert(ret == 1);
1194
1195         /* create_session true above, so pid == sid */
1196         sid = getsid(pid);
1197         assert(pid == sid);
1198
1199         ret = kill(pid, SIGTERM);
1200         assert(ret == 0);
1201
1202         n = read(fd[0], &ret, sizeof(ret));
1203         assert(n == sizeof(ret));
1204         assert(ret == 3);
1205
1206         pid2 = waitpid(pid, &ret, 0);
1207         assert(pid2 == pid);
1208         assert(WEXITSTATUS(ret) == 0);
1209
1210         close(fd[0]);
1211 }
1212
1213 /*
1214  * test9
1215  *
1216  * Confirm that do_fork causes the daemon to be forked as a separate child
1217  */
1218
1219 static void test9(TALLOC_CTX *mem_ctx, const char *pidfile,
1220                   const char *sockpath)
1221 {
1222         int fd[2];
1223         pid_t pid, pid2;
1224         int ret;
1225         struct tevent_context *ev;
1226         struct sock_daemon_context *sockd;
1227         ssize_t n;
1228         int pidfile_fd;
1229         char pidstr[20] = { 0 };
1230         struct stat st;
1231
1232         ret = pipe(fd);
1233         assert(ret == 0);
1234
1235         pid = fork();
1236         assert(pid != -1);
1237
1238         if (pid == 0) {
1239                 close(fd[0]);
1240
1241                 ev = tevent_context_init(mem_ctx);
1242                 assert(ev != NULL);
1243
1244                 /* Reuse test2 funcs for the startup synchronisation */
1245                 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1246                                         &test2_funcs, &fd[1], &sockd);
1247                 assert(ret == 0);
1248
1249                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1250                 assert(ret == EINTR);
1251
1252                 exit(0);
1253         }
1254
1255         close(fd[1]);
1256
1257         n = read(fd[0], &ret, sizeof(ret));
1258         assert(n == sizeof(ret));
1259         assert(ret == 1);
1260
1261         /* do_fork false above, so pid should be active */
1262         ret = kill(pid, 0);
1263         assert(ret == 0);
1264
1265         ret = kill(pid, SIGTERM);
1266         assert(ret == 0);
1267
1268         n = read(fd[0], &ret, sizeof(ret));
1269         assert(n == sizeof(ret));
1270         assert(ret == 3);
1271
1272         pid2 = waitpid(pid, &ret, 0);
1273         assert(pid2 == pid);
1274         assert(WEXITSTATUS(ret) == 0);
1275
1276         close(fd[0]);
1277
1278         ret = pipe(fd);
1279         assert(ret == 0);
1280
1281         pid = fork();
1282         assert(pid != -1);
1283
1284         if (pid == 0) {
1285                 close(fd[0]);
1286
1287                 ev = tevent_context_init(mem_ctx);
1288                 assert(ev != NULL);
1289
1290                 /* Reuse test2 funcs for the startup synchronisation */
1291                 ret = sock_daemon_setup(mem_ctx, "test9", "file:", "NOTICE",
1292                                         &test2_funcs, &fd[1], &sockd);
1293                 assert(ret == 0);
1294
1295                 ret = sock_daemon_run(ev, sockd, pidfile, true, false, -1);
1296                 assert(ret == EINTR);
1297
1298                 exit(0);
1299         }
1300
1301         close(fd[1]);
1302
1303         n = read(fd[0], &ret, sizeof(ret));
1304         assert(n == sizeof(ret));
1305         assert(ret == 1);
1306
1307         /* do_fork true above, so pid should have exited */
1308         pid2 = waitpid(pid, &ret, 0);
1309         assert(pid2 == pid);
1310         assert(WEXITSTATUS(ret) == 0);
1311
1312         pidfile_fd = open(pidfile, O_RDONLY, 0644);
1313         assert(pidfile_fd != -1);
1314         n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1315         assert(n != -1);
1316         pid2 = (pid_t)atoi(pidstr);
1317         assert(pid != pid2);
1318
1319         ret = kill(pid2, SIGTERM);
1320         assert(ret == 0);
1321
1322         n = read(fd[0], &ret, sizeof(ret));
1323         assert(n == sizeof(ret));
1324         assert(ret == 3);
1325
1326         /*
1327          * pid2 isn't our child, so can't call waitpid().  kill(pid2, 0)
1328          * is unreliable - pid2 may have been recycled.  Above indicates
1329          * that the shutdown function was called, so just do 1 final
1330          * check to see if pidfile has been removed.
1331          */
1332         ret = stat(sockpath, &st);
1333         assert(ret == -1);
1334
1335         close(fd[0]);
1336 }
1337
1338 /*
1339  * test10
1340  *
1341  * Confirm that the daemon starts successfully if there is a stale socket
1342  */
1343
1344 static void test10(TALLOC_CTX *mem_ctx, const char *pidfile,
1345                   const char *sockpath)
1346 {
1347         struct stat st;
1348         int fd[2];
1349         pid_t pid, pid2;
1350         int ret;
1351         ssize_t n;
1352         int pidfile_fd;
1353         char pidstr[20] = { 0 };
1354
1355         ret = pipe(fd);
1356         assert(ret == 0);
1357
1358         pid = fork();
1359         assert(pid != -1);
1360
1361         if (pid == 0) {
1362                 struct tevent_context *ev;
1363                 struct sock_daemon_context *sockd;
1364
1365                 close(fd[0]);
1366
1367                 ev = tevent_context_init(mem_ctx);
1368                 assert(ev != NULL);
1369
1370                 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1371                                         &test2_funcs, &fd[1], &sockd);
1372                 assert(ret == 0);
1373
1374                 ret = sock_daemon_add_unix(sockd, sockpath,
1375                                            &dummy_socket_funcs, NULL);
1376                 assert(ret == 0);
1377
1378                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1379                 assert(ret == EINTR);
1380
1381                 exit(0);
1382         }
1383
1384         close(fd[1]);
1385
1386         n = read(fd[0], &ret, sizeof(ret));
1387         assert(n == sizeof(ret));
1388         assert(ret == 1);
1389
1390         /* KILL will leave PID file and socket behind */
1391         ret = kill (pid, SIGKILL);
1392         assert(ret == 0);
1393
1394         ret = stat(sockpath, &st);
1395         assert(ret == 0);
1396
1397         close(fd[0]);
1398
1399         ret = pipe(fd);
1400         assert(ret == 0);
1401
1402         pid = fork();
1403         assert(pid != -1);
1404
1405         if (pid == 0) {
1406                 struct tevent_context *ev;
1407                 struct sock_daemon_context *sockd;
1408
1409                 close(fd[0]);
1410
1411                 ev = tevent_context_init(mem_ctx);
1412                 assert(ev != NULL);
1413
1414                 ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE",
1415                                         &test2_funcs, &fd[1], &sockd);
1416                 assert(ret == 0);
1417
1418                 ret = sock_daemon_add_unix(sockd, sockpath,
1419                                            &dummy_socket_funcs, NULL);
1420                 assert(ret == 0);
1421
1422                 ret = sock_daemon_run(ev, sockd, pidfile, false, false, -1);
1423                 assert(ret == EINTR);
1424
1425                 exit(0);
1426         }
1427
1428         close(fd[1]);
1429
1430         n = read(fd[0], &ret, sizeof(ret));
1431         assert(n == sizeof(ret));
1432         assert(ret == 1);
1433
1434         ret = stat(pidfile, &st);
1435         assert(ret == 0);
1436         assert(S_ISREG(st.st_mode));
1437
1438         pidfile_fd = open(pidfile, O_RDONLY, 0644);
1439         assert(pidfile_fd != -1);
1440         n = read(pidfile_fd, pidstr, sizeof(pidstr)-1);
1441         assert(n != -1);
1442         pid2 = (pid_t)atoi(pidstr);
1443         assert(pid == pid2);
1444
1445         ret = kill(pid, SIGTERM);
1446         assert(ret == 0);
1447
1448         n = read(fd[0], &ret, sizeof(ret));
1449         assert(n == sizeof(ret));
1450         assert(ret == 3);
1451
1452         pid2 = waitpid(pid, &ret, 0);
1453         assert(pid2 == pid);
1454         assert(WEXITSTATUS(ret) == 0);
1455
1456         close(fd[0]);
1457
1458         ret = stat(pidfile, &st);
1459         assert(ret == -1);
1460
1461         ret = stat(sockpath, &st);
1462         assert(ret == -1);
1463 }
1464
1465 int main(int argc, const char **argv)
1466 {
1467         TALLOC_CTX *mem_ctx;
1468         const char *pidfile, *sockpath;
1469         int num;
1470
1471         if (argc != 4) {
1472                 fprintf(stderr, "%s <pidfile> <sockpath> <testnum>\n", argv[0]);
1473                 exit(1);
1474         }
1475
1476         pidfile = argv[1];
1477         sockpath = argv[2];
1478         num = atoi(argv[3]);
1479
1480         mem_ctx = talloc_new(NULL);
1481         assert(mem_ctx != NULL);
1482
1483         switch (num) {
1484         case 1:
1485                 test1(mem_ctx, pidfile, sockpath);
1486                 break;
1487
1488         case 2:
1489                 test2(mem_ctx, pidfile, sockpath);
1490                 break;
1491
1492         case 3:
1493                 test3(mem_ctx, pidfile, sockpath);
1494                 break;
1495
1496         case 4:
1497                 test4(mem_ctx, pidfile, sockpath);
1498                 break;
1499
1500         case 5:
1501                 test5(mem_ctx, pidfile, sockpath);
1502                 break;
1503
1504         case 6:
1505                 test6(mem_ctx, pidfile, sockpath);
1506                 break;
1507
1508         case 7:
1509                 test7(mem_ctx, pidfile, sockpath);
1510                 break;
1511
1512         case 8:
1513                 test8(mem_ctx, pidfile, sockpath);
1514                 break;
1515
1516         case 9:
1517                 test9(mem_ctx, pidfile, sockpath);
1518                 break;
1519
1520         case 10:
1521                 test10(mem_ctx, pidfile, sockpath);
1522                 break;
1523
1524         default:
1525                 fprintf(stderr, "Unknown test number %d\n", num);
1526         }
1527
1528         return 0;
1529 }