ctdb-common: Return script_list for zero scripts
[samba.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_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         state->script_list = talloc_zero(state, struct run_event_script_list);
663         if (tevent_req_nomem(state->script_list, req)) {
664                 return tevent_req_post(req, ev);
665         }
666
667         /*
668          * If monitor event is running,
669          *   cancel the running monitor event and run new event
670          *
671          * If any other event is running,
672          *   if new event is monitor, cancel that event
673          *   else add new event to the queue
674          */
675
676         current_req = run_event_get_running(run_ctx, &monitor_running);
677         if (current_req != NULL) {
678                 if (monitor_running) {
679                         run_event_cancel(current_req);
680                 } else if (strcmp(event_str, "monitor") == 0) {
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         struct run_event_script_list *script_list;
718         int ret;
719         bool is_monitor = false;
720
721         D_DEBUG("Running event %s with args \"%s\"\n", state->event_str,
722                 state->arg_str == NULL ? "(null)" : state->arg_str);
723
724         ret = get_script_list(state,
725                               run_event_script_dir(state->run_ctx),
726                               &script_list);
727         if (ret != 0) {
728                 D_ERR("get_script_list() failed, ret=%d\n", ret);
729                 tevent_req_error(req, ret);
730                 return;
731         }
732
733         /* No scripts */
734         if (script_list == NULL || script_list->num_scripts == 0) {
735                 tevent_req_done(req);
736                 return;
737         }
738
739         talloc_free(state->script_list);
740         state->script_list = script_list;
741
742         ret = script_args(state, state->event_str, state->arg_str,
743                           &state->argv);
744         if (ret != 0) {
745                 D_ERR("script_args() failed, ret=%d\n", ret);
746                 tevent_req_error(req, ret);
747                 return;
748         }
749
750         state->index = 0;
751
752         subreq = run_event_run_script(req);
753         if (tevent_req_nomem(subreq, req)) {
754                 return;
755         }
756         tevent_req_set_callback(subreq, run_event_next_script, req);
757
758         state->script_subreq = subreq;
759
760         if (strcmp(state->event_str, "monitor") == 0) {
761                 is_monitor = true;
762         }
763         run_event_start_running(state->run_ctx, req, is_monitor);
764 }
765
766 static struct tevent_req *run_event_run_script(struct tevent_req *req)
767 {
768         struct run_event_state *state = tevent_req_data(
769                 req, struct run_event_state);
770         struct run_event_script *script;
771         struct tevent_req *subreq;
772         char *path;
773
774         script = &state->script_list->script[state->index];
775
776         path = talloc_asprintf(state, "%s/%s.script",
777                                run_event_script_dir(state->run_ctx),
778                                script->name);
779         if (path == NULL) {
780                 return NULL;
781         }
782
783         state->argv[0] = script->name;
784         script->begin = tevent_timeval_current();
785
786         D_DEBUG("Running %s with args \"%s %s\"\n",
787                 path, state->argv[0], state->argv[1]);
788
789         subreq = run_proc_send(state, state->ev,
790                                run_event_run_proc_context(state->run_ctx),
791                                path, state->argv, -1, state->timeout);
792
793         talloc_free(path);
794
795         return subreq;
796 }
797
798 static void run_event_next_script(struct tevent_req *subreq)
799 {
800         struct tevent_req *req = tevent_req_callback_data(
801                 subreq, struct tevent_req);
802         struct run_event_state *state = tevent_req_data(
803                 req, struct run_event_state);
804         struct run_event_script *script;
805         pid_t pid;
806         int ret;
807         bool status;
808
809         script = &state->script_list->script[state->index];
810         script->end = tevent_timeval_current();
811
812         status = run_proc_recv(subreq, &ret, &script->result, &pid,
813                                state->script_list, &script->output);
814         TALLOC_FREE(subreq);
815         state->script_subreq = NULL;
816         if (! status) {
817                 D_ERR("run_proc failed for %s, ret=%d\n", script->name, ret);
818                 tevent_req_error(req, ret);
819                 return;
820         }
821
822         if (state->cancelled) {
823                 return;
824         }
825
826         /* Log output */
827         if (script->output != NULL) {
828                 debug_log(DEBUG_ERR, script->output, script->name);
829         }
830
831         D_DEBUG("Script %s finished sig=%d, err=%d, status=%d\n",
832                 script->name, script->result.sig, script->result.err,
833                 script->result.status);
834
835
836         /* If a script fails, stop running */
837         script->summary = run_event_script_status(script);
838         if (script->summary != 0 && script->summary != -ENOEXEC) {
839                 state->script_list->num_scripts = state->index + 1;
840
841                 if (script->summary == -ETIME && pid != -1) {
842                         run_event_debug(req, pid);
843                 }
844
845                 state->script_list->summary = script->summary;
846                 D_NOTICE("%s event %s\n", state->event_str,
847                          (script->summary == -ETIME) ? "timed out" : "failed");
848
849                 run_event_stop_running(state->run_ctx);
850                 tevent_req_done(req);
851                 return;
852         }
853
854         state->index += 1;
855
856         /* All scripts executed */
857         if (state->index >= state->script_list->num_scripts) {
858                 run_event_stop_running(state->run_ctx);
859                 tevent_req_done(req);
860                 return;
861         }
862
863         subreq = run_event_run_script(req);
864         if (tevent_req_nomem(subreq, req)) {
865                 return;
866         }
867         tevent_req_set_callback(subreq, run_event_next_script, req);
868
869         state->script_subreq = subreq;
870 }
871
872 static void run_event_debug(struct tevent_req *req, pid_t pid)
873 {
874         struct run_event_state *state = tevent_req_data(
875                 req, struct run_event_state);
876         struct tevent_req *subreq;
877
878         /* Debug script is run with ectx as the memory context */
879         subreq = run_debug_send(state->run_ctx, state->ev, state->run_ctx,
880                                 state->event_str, pid);
881         if (subreq == NULL) {
882                 /* If run debug fails, it's not an error */
883                 D_NOTICE("Failed to run event debug\n");
884                 return;
885         }
886         tevent_req_set_callback(subreq, run_event_debug_done, NULL);
887 }
888
889 static void run_event_debug_done(struct tevent_req *subreq)
890 {
891         int ret = 0;
892         bool status;
893
894         status = run_debug_recv(subreq, &ret);
895         TALLOC_FREE(subreq);
896         if (! status) {
897                 D_NOTICE("run_debug() failed, ret=%d\n", ret);
898         }
899 }
900
901 bool run_event_recv(struct tevent_req *req, int *perr,
902                     TALLOC_CTX *mem_ctx,
903                     struct run_event_script_list **script_list)
904 {
905         struct run_event_state *state = tevent_req_data(
906                 req, struct run_event_state);
907         int ret;
908
909         if (tevent_req_is_unix_error(req, &ret)) {
910                 if (perr != NULL) {
911                         *perr = ret;
912                 }
913                 return false;
914         }
915
916         if (script_list != NULL) {
917                 *script_list = talloc_steal(mem_ctx, state->script_list);
918         }
919         return true;
920 }
921