ctdb-common: Do not initialize run_proc inside run_event
[kai/samba-autobuild/.git] / ctdb / common / run_event.c
1 /*
2    Run scripts in a directory with specific event arguments
3
4    Copyright (C) Amitay Isaacs  2017
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/dir.h"
23 #include "system/glob.h"
24 #include "system/wait.h"
25
26 #include <talloc.h>
27 #include <tevent.h>
28
29 #include "lib/util/tevent_unix.h"
30 #include "lib/util/debug.h"
31
32 #include "common/logging.h"
33 #include "common/run_proc.h"
34 #include "common/run_event.h"
35
36 /*
37  * Utility functions
38  */
39
40 static int script_filter(const struct dirent *de)
41 {
42         int ret;
43
44         /* Match a script pattern */
45         ret = fnmatch("[0-9][0-9].*.script", de->d_name, 0);
46         if (ret == 0) {
47                 return 1;
48         }
49
50         return 0;
51 }
52
53 static int get_script_list(TALLOC_CTX *mem_ctx,
54                            const char *script_dir,
55                            struct run_event_script_list **out)
56 {
57         struct dirent **namelist = NULL;
58         struct run_event_script_list *script_list;
59         size_t ls;
60         int count, ret;
61         int i;
62
63         count = scandir(script_dir, &namelist, script_filter, alphasort);
64         if (count == -1) {
65                 ret = errno;
66                 if (ret == ENOENT) {
67                         D_WARNING("event script dir %s removed\n", script_dir);
68                 } else {
69                         D_WARNING("scandir() failed on %s, ret=%d\n",
70                                   script_dir, ret);
71                 }
72                 *out = NULL;
73                 ret = 0;
74                 goto done;
75         }
76
77         if (count == 0) {
78                 *out = NULL;
79                 ret = 0;
80                 goto done;
81         }
82
83         script_list = talloc_zero(mem_ctx, struct run_event_script_list);
84         if (script_list == NULL) {
85                 return ENOMEM;
86         }
87
88         script_list->num_scripts = count;
89         script_list->script = talloc_zero_array(script_list,
90                                                 struct run_event_script,
91                                                 count);
92         if (script_list->script == NULL) {
93                 ret = ENOMEM;
94                 talloc_free(script_list);
95                 goto done;
96         }
97
98         ls = strlen(".script");
99         for (i=0; i<count; i++) {
100                 struct run_event_script *s = &script_list->script[i];
101
102                 s->name = talloc_strndup(script_list,
103                                          namelist[i]->d_name,
104                                          strlen(namelist[i]->d_name) - ls);
105                 if (s->name == NULL) {
106                         ret = ENOMEM;
107                         talloc_free(script_list);
108                         goto done;
109                 }
110         }
111
112         *out = script_list;
113         ret = 0;
114
115 done:
116         if (namelist != NULL && count != -1) {
117                 for (i=0; i<count; i++) {
118                         free(namelist[i]);
119                 }
120                 free(namelist);
121         }
122         return ret;
123 }
124
125 static int script_chmod(TALLOC_CTX *mem_ctx, const char *script_dir,
126                         const char *script_name, bool enable)
127 {
128         DIR *dirp;
129         struct dirent *de;
130         char script_file[PATH_MAX];
131         int ret, new_mode;
132         char *filename;
133         struct stat st;
134         bool found;
135         int fd = -1;
136
137         ret = snprintf(script_file,
138                        sizeof(script_file),
139                        "%s.script",
140                        script_name);
141         if (ret >= sizeof(script_file)) {
142                 return ENAMETOOLONG;
143         }
144
145         dirp = opendir(script_dir);
146         if (dirp == NULL) {
147                 return errno;
148         }
149
150         found = false;
151         while ((de = readdir(dirp)) != NULL) {
152                 if (strcmp(de->d_name, script_file) == 0) {
153
154                         /* check for valid script names */
155                         ret = script_filter(de);
156                         if (ret == 0) {
157                                 closedir(dirp);
158                                 return EINVAL;
159                         }
160
161                         found = true;
162                         break;
163                 }
164         }
165         closedir(dirp);
166
167         if (! found) {
168                 return ENOENT;
169         }
170
171         filename = talloc_asprintf(mem_ctx, "%s/%s", script_dir, script_file);
172         if (filename == NULL) {
173                 return ENOMEM;
174         }
175
176         fd = open(filename, O_RDWR);
177         if (fd == -1) {
178                 ret = errno;
179                 goto done;
180         }
181
182         ret = fstat(fd, &st);
183         if (ret != 0) {
184                 ret = errno;
185                 goto done;
186         }
187
188         if (enable) {
189                 new_mode = st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH);
190         } else {
191                 new_mode = st.st_mode & ~(S_IXUSR | S_IXGRP | S_IXOTH);
192         }
193
194         ret = fchmod(fd, new_mode);
195         if (ret != 0) {
196                 ret = errno;
197                 goto done;
198         }
199
200 done:
201         if (fd != -1) {
202                 close(fd);
203         }
204         talloc_free(filename);
205         return ret;
206 }
207
208 static int script_args(TALLOC_CTX *mem_ctx, const char *event_str,
209                        const char *arg_str, const char ***out)
210 {
211         const char **argv;
212         int argc;
213         size_t len;
214
215         /* Preallocate argv array to avoid reallocation. */
216         len = 8;
217         argv = talloc_array(mem_ctx, const char *, len);
218         if (argv == NULL) {
219                 return ENOMEM;
220         }
221
222         argv[0] = NULL; /* script name */
223         argv[1] = event_str;
224         argc = 2;
225
226         if (arg_str != NULL) {
227                 char *str, *t, *tok;
228
229                 str = talloc_strdup(argv, arg_str);
230                 if (str == NULL) {
231                         return ENOMEM;
232                 }
233
234                 t = str;
235                 while ((tok = strtok(t, " ")) != NULL) {
236                         argv[argc] = talloc_strdup(argv, tok);
237                         if (argv[argc] == NULL) {
238                                 talloc_free(argv);
239                                 return ENOMEM;
240                         }
241                         argc += 1;
242                         if (argc >= len) {
243                                 argv = talloc_realloc(mem_ctx, argv,
244                                                       const char *, len + 8);
245                                 if (argv == NULL) {
246                                         return ENOMEM;
247                                 }
248                                 len += 8;
249                         }
250                         t = NULL;
251                 }
252
253                 talloc_free(str);
254         }
255
256         argv[argc] = NULL;
257         argc += 1;
258
259         *out = argv;
260         return 0;
261 }
262
263 struct run_event_context {
264         struct run_proc_context *run_proc_ctx;
265         const char *script_dir;
266         const char *debug_prog;
267         bool debug_running;
268
269         struct tevent_queue *queue;
270         struct tevent_req *current_req;
271         bool monitor_running;
272 };
273
274
275 int run_event_init(TALLOC_CTX *mem_ctx, struct run_proc_context *run_proc_ctx,
276                    const char *script_dir, const char *debug_prog,
277                    struct run_event_context **out)
278 {
279         struct run_event_context *run_ctx;
280         struct stat st;
281         int ret;
282
283         run_ctx = talloc_zero(mem_ctx, struct run_event_context);
284         if (run_ctx == NULL) {
285                 return ENOMEM;
286         }
287
288         run_ctx->run_proc_ctx = run_proc_ctx;
289
290         ret = stat(script_dir, &st);
291         if (ret != 0) {
292                 ret = errno;
293                 talloc_free(run_ctx);
294                 return ret;
295         }
296
297         if (! S_ISDIR(st.st_mode)) {
298                 talloc_free(run_ctx);
299                 return EINVAL;
300         }
301
302         run_ctx->script_dir = talloc_strdup(run_ctx, script_dir);
303         if (run_ctx->script_dir == NULL) {
304                 talloc_free(run_ctx);
305                 return ENOMEM;
306         }
307
308         if (debug_prog != NULL) {
309                 run_ctx->debug_prog = talloc_strdup(run_ctx, debug_prog);
310                 if (run_ctx->debug_prog == NULL) {
311                         talloc_free(run_ctx);
312                         return ENOMEM;
313                 }
314         }
315
316         run_ctx->debug_running = false;
317
318         run_ctx->queue = tevent_queue_create(run_ctx, "run event queue");
319         if (run_ctx->queue == NULL) {
320                 talloc_free(run_ctx);
321                 return ENOMEM;
322         }
323
324         run_ctx->monitor_running = false;
325
326         *out = run_ctx;
327         return 0;
328 }
329
330 static struct run_proc_context *
331 run_event_run_proc_context(struct run_event_context *run_ctx)
332 {
333         return run_ctx->run_proc_ctx;
334 }
335
336 static const char *run_event_script_dir(struct run_event_context *run_ctx)
337 {
338         return run_ctx->script_dir;
339 }
340
341 static const char *run_event_debug_prog(struct run_event_context *run_ctx)
342 {
343         return run_ctx->debug_prog;
344 }
345
346 static struct tevent_queue *run_event_queue(struct run_event_context *run_ctx)
347 {
348         return run_ctx->queue;
349 }
350
351 static void run_event_start_running(struct run_event_context *run_ctx,
352                                     struct tevent_req *req, bool is_monitor)
353 {
354         run_ctx->current_req = req;
355         run_ctx->monitor_running = is_monitor;
356 }
357
358 static void run_event_stop_running(struct run_event_context *run_ctx)
359 {
360         run_ctx->current_req = NULL;
361         run_ctx->monitor_running = false;
362 }
363
364 static struct tevent_req *run_event_get_running(
365                                 struct run_event_context *run_ctx,
366                                 bool *is_monitor)
367 {
368         *is_monitor = run_ctx->monitor_running;
369         return run_ctx->current_req;
370 }
371
372 static int run_event_script_status(struct run_event_script *script)
373 {
374         int ret;
375
376         if (script->result.sig > 0) {
377                 ret = -EINTR;
378         } else if (script->result.err > 0) {
379                 if (script->result.err == EACCES) {
380                         /* Map EACCESS to ENOEXEC */
381                         ret = -ENOEXEC;
382                 } else {
383                         ret = -script->result.err;
384                 }
385         } else {
386                 ret = script->result.status;
387         }
388
389         return ret;
390 }
391
392 int run_event_script_list(struct run_event_context *run_ctx,
393                           TALLOC_CTX *mem_ctx,
394                           struct run_event_script_list **output)
395 {
396         struct run_event_script_list *script_list;
397         int ret, i;
398
399         ret = get_script_list(mem_ctx, run_event_script_dir(run_ctx),
400                               &script_list);
401         if (ret != 0) {
402                 return ret;
403         }
404
405         if (script_list == NULL) {
406                 *output = NULL;
407                 return 0;
408         }
409
410         for (i=0; i<script_list->num_scripts; i++) {
411                 struct run_event_script *script = &script_list->script[i];
412                 struct stat st;
413                 char *path = NULL;
414
415                 path = talloc_asprintf(mem_ctx, "%s/%s.script",
416                                        run_event_script_dir(run_ctx),
417                                        script->name);
418                 if (path == NULL) {
419                         continue;
420                 }
421
422                 ret = stat(path, &st);
423                 if (ret != 0) {
424                         TALLOC_FREE(path);
425                         continue;
426                 }
427
428                 if (! (st.st_mode & S_IXUSR)) {
429                         script->summary = -ENOEXEC;
430                 }
431
432                 TALLOC_FREE(path);
433         }
434
435         *output = script_list;
436         return 0;
437 }
438
439 int run_event_script_enable(struct run_event_context *run_ctx,
440                             const char *script_name)
441 {
442         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
443                             script_name, true);
444 }
445
446 int run_event_script_disable(struct run_event_context *run_ctx,
447                              const char *script_name)
448 {
449         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
450                             script_name, false);
451 }
452
453 /*
454  * Run debug program to diagnose hung scripts
455  */
456
457 static int debug_args(TALLOC_CTX *mem_ctx, const char *path,
458                       const char *event_str, pid_t pid, const char ***out)
459 {
460         const char **argv;
461
462         argv = talloc_array(mem_ctx, const char *, 4);
463         if (argv == NULL) {
464                 return ENOMEM;
465         }
466
467         argv[0] = path;
468         argv[1] = talloc_asprintf(argv, "%d", pid);
469         argv[2] = event_str;
470         if (argv[1] == NULL) {
471                 talloc_free(argv);
472                 return ENOMEM;
473         }
474         argv[3] = NULL;
475
476         *out = argv;
477         return 0;
478 }
479
480 static void debug_log(int loglevel, const char *output, const char *log_prefix)
481 {
482         char *line, *s;
483
484         s = strdup(output);
485         if (s == NULL) {
486                 DEBUG(loglevel, ("%s: %s\n", log_prefix, output));
487                 return;
488         }
489
490         line = strtok(s, "\n");
491         while (line != NULL) {
492                 DEBUG(loglevel, ("%s: %s\n", log_prefix, line));
493                 line = strtok(NULL, "\n");
494         }
495         free(s);
496 }
497
498 struct run_debug_state {
499         struct run_event_context *run_ctx;
500         pid_t pid;
501 };
502
503 static void run_debug_done(struct tevent_req *subreq);
504
505 static struct tevent_req *run_debug_send(TALLOC_CTX *mem_ctx,
506                                          struct tevent_context *ev,
507                                          struct run_event_context *run_ctx,
508                                          const char *event_str, pid_t pid)
509 {
510         struct tevent_req *req, *subreq;
511         struct run_debug_state *state;
512         const char **argv;
513         const char *debug_prog;
514         int ret;
515
516         req = tevent_req_create(mem_ctx, &state, struct run_debug_state);
517         if (req == NULL) {
518                 return NULL;
519         }
520
521         state->run_ctx = run_ctx;
522         state->pid = pid;
523
524         debug_prog = run_event_debug_prog(run_ctx);
525         if (debug_prog == NULL) {
526                 tevent_req_done(req);
527                 return tevent_req_post(req, ev);
528         }
529
530         if (run_ctx->debug_running) {
531                 tevent_req_done(req);
532                 return tevent_req_post(req, ev);
533         }
534
535         if (pid == -1) {
536                 D_DEBUG("Event script terminated, nothing to debug\n");
537                 tevent_req_done(req);
538                 return tevent_req_post(req, ev);
539         }
540
541         ret = debug_args(state, debug_prog, event_str, pid, &argv);
542         if (ret != 0) {
543                 D_ERR("debug_args() failed\n");
544                 tevent_req_error(req, ret);
545                 return tevent_req_post(req, ev);
546         }
547
548         D_DEBUG("Running debug %s with args \"%s %s\"\n",
549                 debug_prog, argv[1], argv[2]);
550
551         subreq = run_proc_send(state, ev, run_event_run_proc_context(run_ctx),
552                                debug_prog, argv, -1, tevent_timeval_zero());
553         if (tevent_req_nomem(subreq, req)) {
554                 return tevent_req_post(req, ev);
555         }
556         tevent_req_set_callback(subreq, run_debug_done, req);
557
558         run_ctx->debug_running = true;
559
560         talloc_free(argv);
561         return req;
562 }
563
564 static void run_debug_done(struct tevent_req *subreq)
565 {
566         struct tevent_req *req = tevent_req_callback_data(
567                 subreq, struct tevent_req);
568         struct run_debug_state *state = tevent_req_data(
569                 req, struct run_debug_state);
570         char *output;
571         int ret;
572         bool status;
573
574         state->run_ctx->debug_running = false;
575
576         status = run_proc_recv(subreq, &ret, NULL, NULL, state, &output);
577         TALLOC_FREE(subreq);
578         if (! status) {
579                 D_ERR("Running debug failed, ret=%d\n", ret);
580         }
581
582         /* Log output */
583         if (output != NULL) {
584                 debug_log(DEBUG_ERR, output, "event_debug");
585                 talloc_free(output);
586         }
587
588         kill(-state->pid, SIGTERM);
589         tevent_req_done(req);
590 }
591
592 static bool run_debug_recv(struct tevent_req *req, int *perr)
593 {
594         int ret;
595
596         if (tevent_req_is_unix_error(req, &ret)) {
597                 if (perr != NULL) {
598                         *perr = ret;
599                 }
600                 return false;
601         }
602
603         return true;
604 }
605
606 /*
607  * Run a single event
608  */
609
610 struct run_event_state {
611         struct tevent_context *ev;
612         struct run_event_context *run_ctx;
613         const char *event_str;
614         const char *arg_str;
615         struct timeval timeout;
616
617         struct run_event_script_list *script_list;
618         const char **argv;
619         struct tevent_req *script_subreq;
620         int index;
621         bool cancelled;
622 };
623
624 static void run_event_cancel(struct tevent_req *req);
625 static void run_event_trigger(struct tevent_req *req, void *private_data);
626 static struct tevent_req *run_event_run_script(struct tevent_req *req);
627 static void run_event_next_script(struct tevent_req *subreq);
628 static void run_event_debug(struct tevent_req *req, pid_t pid);
629 static void run_event_debug_done(struct tevent_req *subreq);
630
631 struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
632                                   struct tevent_context *ev,
633                                   struct run_event_context *run_ctx,
634                                   const char *event_str,
635                                   const char *arg_str,
636                                   struct timeval timeout)
637 {
638         struct tevent_req *req, *current_req;
639         struct run_event_state *state;
640         bool monitor_running, status;
641
642         req = tevent_req_create(mem_ctx, &state, struct run_event_state);
643         if (req == NULL) {
644                 return NULL;
645         }
646
647         state->ev = ev;
648         state->run_ctx = run_ctx;
649         state->event_str = talloc_strdup(state, event_str);
650         if (tevent_req_nomem(state->event_str, req)) {
651                 return tevent_req_post(req, ev);
652         }
653         if (arg_str != NULL) {
654                 state->arg_str = talloc_strdup(state, arg_str);
655                 if (tevent_req_nomem(state->arg_str, req)) {
656                         return tevent_req_post(req, ev);
657                 }
658         }
659         state->timeout = timeout;
660         state->cancelled = false;
661
662         /*
663          * If monitor event is running,
664          *   cancel the running monitor event and run new event
665          *
666          * If any other event is running,
667          *   if new event is monitor, cancel that event
668          *   else add new event to the queue
669          */
670
671         current_req = run_event_get_running(run_ctx, &monitor_running);
672         if (current_req != NULL) {
673                 if (monitor_running) {
674                         run_event_cancel(current_req);
675                 } else if (strcmp(event_str, "monitor") == 0) {
676                         state->script_list = talloc_zero(
677                                 state, struct run_event_script_list);
678                         if (tevent_req_nomem(state->script_list, req)) {
679                                 return tevent_req_post(req, ev);
680                         }
681                         state->script_list->summary = -ECANCELED;
682                         tevent_req_done(req);
683                         return tevent_req_post(req, ev);
684                 }
685         }
686
687         status = tevent_queue_add(run_event_queue(run_ctx), ev, req,
688                                   run_event_trigger, NULL);
689         if (! status) {
690                 tevent_req_error(req, ENOMEM);
691                 return tevent_req_post(req, ev);
692         }
693
694         return req;
695 }
696
697 static void run_event_cancel(struct tevent_req *req)
698 {
699         struct run_event_state *state = tevent_req_data(
700                 req, struct run_event_state);
701
702         run_event_stop_running(state->run_ctx);
703
704         state->script_list->summary = -ECANCELED;
705         state->cancelled = true;
706
707         TALLOC_FREE(state->script_subreq);
708
709         tevent_req_done(req);
710 }
711
712 static void run_event_trigger(struct tevent_req *req, void *private_data)
713 {
714         struct tevent_req *subreq;
715         struct run_event_state *state = tevent_req_data(
716                 req, struct run_event_state);
717         int ret;
718         bool is_monitor = false;
719
720         D_DEBUG("Running event %s with args \"%s\"\n", state->event_str,
721                 state->arg_str == NULL ? "(null)" : state->arg_str);
722
723         ret = get_script_list(state, run_event_script_dir(state->run_ctx),
724                               &state->script_list);
725         if (ret != 0) {
726                 D_ERR("get_script_list() failed, ret=%d\n", ret);
727                 tevent_req_error(req, ret);
728                 return;
729         }
730
731         /* No scripts */
732         if (state->script_list == NULL ||
733             state->script_list->num_scripts == 0) {
734                 tevent_req_done(req);
735                 return;
736         }
737
738         ret = script_args(state, state->event_str, state->arg_str,
739                           &state->argv);
740         if (ret != 0) {
741                 D_ERR("script_args() failed, ret=%d\n", ret);
742                 tevent_req_error(req, ret);
743                 return;
744         }
745
746         state->index = 0;
747
748         subreq = run_event_run_script(req);
749         if (tevent_req_nomem(subreq, req)) {
750                 return;
751         }
752         tevent_req_set_callback(subreq, run_event_next_script, req);
753
754         state->script_subreq = subreq;
755
756         if (strcmp(state->event_str, "monitor") == 0) {
757                 is_monitor = true;
758         }
759         run_event_start_running(state->run_ctx, req, is_monitor);
760 }
761
762 static struct tevent_req *run_event_run_script(struct tevent_req *req)
763 {
764         struct run_event_state *state = tevent_req_data(
765                 req, struct run_event_state);
766         struct run_event_script *script;
767         struct tevent_req *subreq;
768         char *path;
769
770         script = &state->script_list->script[state->index];
771
772         path = talloc_asprintf(state, "%s/%s.script",
773                                run_event_script_dir(state->run_ctx),
774                                script->name);
775         if (path == NULL) {
776                 return NULL;
777         }
778
779         state->argv[0] = script->name;
780         script->begin = tevent_timeval_current();
781
782         D_DEBUG("Running %s with args \"%s %s\"\n",
783                 path, state->argv[0], state->argv[1]);
784
785         subreq = run_proc_send(state, state->ev,
786                                run_event_run_proc_context(state->run_ctx),
787                                path, state->argv, -1, state->timeout);
788
789         talloc_free(path);
790
791         return subreq;
792 }
793
794 static void run_event_next_script(struct tevent_req *subreq)
795 {
796         struct tevent_req *req = tevent_req_callback_data(
797                 subreq, struct tevent_req);
798         struct run_event_state *state = tevent_req_data(
799                 req, struct run_event_state);
800         struct run_event_script *script;
801         pid_t pid;
802         int ret;
803         bool status;
804
805         script = &state->script_list->script[state->index];
806         script->end = tevent_timeval_current();
807
808         status = run_proc_recv(subreq, &ret, &script->result, &pid,
809                                state->script_list, &script->output);
810         TALLOC_FREE(subreq);
811         state->script_subreq = NULL;
812         if (! status) {
813                 D_ERR("run_proc failed for %s, ret=%d\n", script->name, ret);
814                 tevent_req_error(req, ret);
815                 return;
816         }
817
818         if (state->cancelled) {
819                 return;
820         }
821
822         /* Log output */
823         if (script->output != NULL) {
824                 debug_log(DEBUG_ERR, script->output, script->name);
825         }
826
827         D_DEBUG("Script %s finished sig=%d, err=%d, status=%d\n",
828                 script->name, script->result.sig, script->result.err,
829                 script->result.status);
830
831
832         /* If a script fails, stop running */
833         script->summary = run_event_script_status(script);
834         if (script->summary != 0 && script->summary != -ENOEXEC) {
835                 state->script_list->num_scripts = state->index + 1;
836
837                 if (script->summary == -ETIME && pid != -1) {
838                         run_event_debug(req, pid);
839                 }
840
841                 state->script_list->summary = script->summary;
842                 D_NOTICE("%s event %s\n", state->event_str,
843                          (script->summary == -ETIME) ? "timed out" : "failed");
844
845                 run_event_stop_running(state->run_ctx);
846                 tevent_req_done(req);
847                 return;
848         }
849
850         state->index += 1;
851
852         /* All scripts executed */
853         if (state->index >= state->script_list->num_scripts) {
854                 run_event_stop_running(state->run_ctx);
855                 tevent_req_done(req);
856                 return;
857         }
858
859         subreq = run_event_run_script(req);
860         if (tevent_req_nomem(subreq, req)) {
861                 return;
862         }
863         tevent_req_set_callback(subreq, run_event_next_script, req);
864
865         state->script_subreq = subreq;
866 }
867
868 static void run_event_debug(struct tevent_req *req, pid_t pid)
869 {
870         struct run_event_state *state = tevent_req_data(
871                 req, struct run_event_state);
872         struct tevent_req *subreq;
873
874         /* Debug script is run with ectx as the memory context */
875         subreq = run_debug_send(state->run_ctx, state->ev, state->run_ctx,
876                                 state->event_str, pid);
877         if (subreq == NULL) {
878                 /* If run debug fails, it's not an error */
879                 D_NOTICE("Failed to run event debug\n");
880                 return;
881         }
882         tevent_req_set_callback(subreq, run_event_debug_done, NULL);
883 }
884
885 static void run_event_debug_done(struct tevent_req *subreq)
886 {
887         int ret = 0;
888         bool status;
889
890         status = run_debug_recv(subreq, &ret);
891         TALLOC_FREE(subreq);
892         if (! status) {
893                 D_NOTICE("run_debug() failed, ret=%d\n", ret);
894         }
895 }
896
897 bool run_event_recv(struct tevent_req *req, int *perr,
898                     TALLOC_CTX *mem_ctx,
899                     struct run_event_script_list **script_list)
900 {
901         struct run_event_state *state = tevent_req_data(
902                 req, struct run_event_state);
903         int ret;
904
905         if (tevent_req_is_unix_error(req, &ret)) {
906                 if (perr != NULL) {
907                         *perr = ret;
908                 }
909                 return false;
910         }
911
912         if (script_list != NULL) {
913                 *script_list = talloc_steal(mem_ctx, state->script_list);
914         }
915         return true;
916 }
917