ctdb-scripts: Event scripts must end with ".script" suffix
[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 tevent_context *ev,
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         ret = run_proc_init(run_ctx, ev, &run_ctx->run_proc_ctx);
289         if (ret != 0) {
290                 talloc_free(run_ctx);
291                 return ret;
292         }
293
294         ret = stat(script_dir, &st);
295         if (ret != 0) {
296                 ret = errno;
297                 talloc_free(run_ctx);
298                 return ret;
299         }
300
301         if (! S_ISDIR(st.st_mode)) {
302                 talloc_free(run_ctx);
303                 return EINVAL;
304         }
305
306         run_ctx->script_dir = talloc_strdup(run_ctx, script_dir);
307         if (run_ctx->script_dir == NULL) {
308                 talloc_free(run_ctx);
309                 return ENOMEM;
310         }
311
312         if (debug_prog != NULL) {
313                 run_ctx->debug_prog = talloc_strdup(run_ctx, debug_prog);
314                 if (run_ctx->debug_prog == NULL) {
315                         talloc_free(run_ctx);
316                         return ENOMEM;
317                 }
318         }
319
320         run_ctx->debug_running = false;
321
322         run_ctx->queue = tevent_queue_create(run_ctx, "run event queue");
323         if (run_ctx->queue == NULL) {
324                 talloc_free(run_ctx);
325                 return ENOMEM;
326         }
327
328         run_ctx->monitor_running = false;
329
330         *out = run_ctx;
331         return 0;
332 }
333
334 static struct run_proc_context *
335 run_event_run_proc_context(struct run_event_context *run_ctx)
336 {
337         return run_ctx->run_proc_ctx;
338 }
339
340 static const char *run_event_script_dir(struct run_event_context *run_ctx)
341 {
342         return run_ctx->script_dir;
343 }
344
345 static const char *run_event_debug_prog(struct run_event_context *run_ctx)
346 {
347         return run_ctx->debug_prog;
348 }
349
350 static struct tevent_queue *run_event_queue(struct run_event_context *run_ctx)
351 {
352         return run_ctx->queue;
353 }
354
355 static void run_event_start_running(struct run_event_context *run_ctx,
356                                     struct tevent_req *req, bool is_monitor)
357 {
358         run_ctx->current_req = req;
359         run_ctx->monitor_running = is_monitor;
360 }
361
362 static void run_event_stop_running(struct run_event_context *run_ctx)
363 {
364         run_ctx->current_req = NULL;
365         run_ctx->monitor_running = false;
366 }
367
368 static struct tevent_req *run_event_get_running(
369                                 struct run_event_context *run_ctx,
370                                 bool *is_monitor)
371 {
372         *is_monitor = run_ctx->monitor_running;
373         return run_ctx->current_req;
374 }
375
376 static int run_event_script_status(struct run_event_script *script)
377 {
378         int ret;
379
380         if (script->result.sig > 0) {
381                 ret = -EINTR;
382         } else if (script->result.err > 0) {
383                 if (script->result.err == EACCES) {
384                         /* Map EACCESS to ENOEXEC */
385                         ret = -ENOEXEC;
386                 } else {
387                         ret = -script->result.err;
388                 }
389         } else {
390                 ret = script->result.status;
391         }
392
393         return ret;
394 }
395
396 int run_event_script_list(struct run_event_context *run_ctx,
397                           TALLOC_CTX *mem_ctx,
398                           struct run_event_script_list **output)
399 {
400         struct run_event_script_list *script_list;
401         int ret, i;
402
403         ret = get_script_list(mem_ctx, run_event_script_dir(run_ctx),
404                               &script_list);
405         if (ret != 0) {
406                 return ret;
407         }
408
409         if (script_list == NULL) {
410                 *output = NULL;
411                 return 0;
412         }
413
414         for (i=0; i<script_list->num_scripts; i++) {
415                 struct run_event_script *script = &script_list->script[i];
416                 struct stat st;
417                 char *path = NULL;
418
419                 path = talloc_asprintf(mem_ctx, "%s/%s.script",
420                                        run_event_script_dir(run_ctx),
421                                        script->name);
422                 if (path == NULL) {
423                         continue;
424                 }
425
426                 ret = stat(path, &st);
427                 if (ret != 0) {
428                         TALLOC_FREE(path);
429                         continue;
430                 }
431
432                 if (! (st.st_mode & S_IXUSR)) {
433                         script->summary = -ENOEXEC;
434                 }
435
436                 TALLOC_FREE(path);
437         }
438
439         *output = script_list;
440         return 0;
441 }
442
443 int run_event_script_enable(struct run_event_context *run_ctx,
444                             const char *script_name)
445 {
446         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
447                             script_name, true);
448 }
449
450 int run_event_script_disable(struct run_event_context *run_ctx,
451                              const char *script_name)
452 {
453         return script_chmod(run_ctx, run_event_script_dir(run_ctx),
454                             script_name, false);
455 }
456
457 /*
458  * Run debug program to diagnose hung scripts
459  */
460
461 static int debug_args(TALLOC_CTX *mem_ctx, const char *path,
462                       const char *event_str, pid_t pid, const char ***out)
463 {
464         const char **argv;
465
466         argv = talloc_array(mem_ctx, const char *, 4);
467         if (argv == NULL) {
468                 return ENOMEM;
469         }
470
471         argv[0] = path;
472         argv[1] = talloc_asprintf(argv, "%d", pid);
473         argv[2] = event_str;
474         if (argv[1] == NULL) {
475                 talloc_free(argv);
476                 return ENOMEM;
477         }
478         argv[3] = NULL;
479
480         *out = argv;
481         return 0;
482 }
483
484 static void debug_log(int loglevel, const char *output, const char *log_prefix)
485 {
486         char *line, *s;
487
488         s = strdup(output);
489         if (s == NULL) {
490                 DEBUG(loglevel, ("%s: %s\n", log_prefix, output));
491                 return;
492         }
493
494         line = strtok(s, "\n");
495         while (line != NULL) {
496                 DEBUG(loglevel, ("%s: %s\n", log_prefix, line));
497                 line = strtok(NULL, "\n");
498         }
499         free(s);
500 }
501
502 struct run_debug_state {
503         struct run_event_context *run_ctx;
504         pid_t pid;
505 };
506
507 static void run_debug_done(struct tevent_req *subreq);
508
509 static struct tevent_req *run_debug_send(TALLOC_CTX *mem_ctx,
510                                          struct tevent_context *ev,
511                                          struct run_event_context *run_ctx,
512                                          const char *event_str, pid_t pid)
513 {
514         struct tevent_req *req, *subreq;
515         struct run_debug_state *state;
516         const char **argv;
517         const char *debug_prog;
518         int ret;
519
520         req = tevent_req_create(mem_ctx, &state, struct run_debug_state);
521         if (req == NULL) {
522                 return NULL;
523         }
524
525         state->run_ctx = run_ctx;
526         state->pid = pid;
527
528         debug_prog = run_event_debug_prog(run_ctx);
529         if (debug_prog == NULL) {
530                 tevent_req_done(req);
531                 return tevent_req_post(req, ev);
532         }
533
534         if (run_ctx->debug_running) {
535                 tevent_req_done(req);
536                 return tevent_req_post(req, ev);
537         }
538
539         if (pid == -1) {
540                 D_DEBUG("Event script terminated, nothing to debug\n");
541                 tevent_req_done(req);
542                 return tevent_req_post(req, ev);
543         }
544
545         ret = debug_args(state, debug_prog, event_str, pid, &argv);
546         if (ret != 0) {
547                 D_ERR("debug_args() failed\n");
548                 tevent_req_error(req, ret);
549                 return tevent_req_post(req, ev);
550         }
551
552         D_DEBUG("Running debug %s with args \"%s %s\"\n",
553                 debug_prog, argv[1], argv[2]);
554
555         subreq = run_proc_send(state, ev, run_event_run_proc_context(run_ctx),
556                                debug_prog, argv, -1, tevent_timeval_zero());
557         if (tevent_req_nomem(subreq, req)) {
558                 return tevent_req_post(req, ev);
559         }
560         tevent_req_set_callback(subreq, run_debug_done, req);
561
562         run_ctx->debug_running = true;
563
564         talloc_free(argv);
565         return req;
566 }
567
568 static void run_debug_done(struct tevent_req *subreq)
569 {
570         struct tevent_req *req = tevent_req_callback_data(
571                 subreq, struct tevent_req);
572         struct run_debug_state *state = tevent_req_data(
573                 req, struct run_debug_state);
574         char *output;
575         int ret;
576         bool status;
577
578         state->run_ctx->debug_running = false;
579
580         status = run_proc_recv(subreq, &ret, NULL, NULL, state, &output);
581         TALLOC_FREE(subreq);
582         if (! status) {
583                 D_ERR("Running debug failed, ret=%d\n", ret);
584         }
585
586         /* Log output */
587         if (output != NULL) {
588                 debug_log(DEBUG_ERR, output, "event_debug");
589                 talloc_free(output);
590         }
591
592         kill(-state->pid, SIGTERM);
593         tevent_req_done(req);
594 }
595
596 static bool run_debug_recv(struct tevent_req *req, int *perr)
597 {
598         int ret;
599
600         if (tevent_req_is_unix_error(req, &ret)) {
601                 if (perr != NULL) {
602                         *perr = ret;
603                 }
604                 return false;
605         }
606
607         return true;
608 }
609
610 /*
611  * Run a single event
612  */
613
614 struct run_event_state {
615         struct tevent_context *ev;
616         struct run_event_context *run_ctx;
617         const char *event_str;
618         const char *arg_str;
619         struct timeval timeout;
620
621         struct run_event_script_list *script_list;
622         const char **argv;
623         struct tevent_req *script_subreq;
624         int index;
625         bool cancelled;
626 };
627
628 static void run_event_cancel(struct tevent_req *req);
629 static void run_event_trigger(struct tevent_req *req, void *private_data);
630 static struct tevent_req *run_event_run_script(struct tevent_req *req);
631 static void run_event_next_script(struct tevent_req *subreq);
632 static void run_event_debug(struct tevent_req *req, pid_t pid);
633 static void run_event_debug_done(struct tevent_req *subreq);
634
635 struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
636                                   struct tevent_context *ev,
637                                   struct run_event_context *run_ctx,
638                                   const char *event_str,
639                                   const char *arg_str,
640                                   struct timeval timeout)
641 {
642         struct tevent_req *req, *current_req;
643         struct run_event_state *state;
644         bool monitor_running, status;
645
646         req = tevent_req_create(mem_ctx, &state, struct run_event_state);
647         if (req == NULL) {
648                 return NULL;
649         }
650
651         state->ev = ev;
652         state->run_ctx = run_ctx;
653         state->event_str = talloc_strdup(state, event_str);
654         if (tevent_req_nomem(state->event_str, req)) {
655                 return tevent_req_post(req, ev);
656         }
657         if (arg_str != NULL) {
658                 state->arg_str = talloc_strdup(state, arg_str);
659                 if (tevent_req_nomem(state->arg_str, req)) {
660                         return tevent_req_post(req, ev);
661                 }
662         }
663         state->timeout = timeout;
664         state->cancelled = false;
665
666         /*
667          * If monitor event is running,
668          *   cancel the running monitor event and run new event
669          *
670          * If any other event is running,
671          *   if new event is monitor, cancel that event
672          *   else add new event to the queue
673          */
674
675         current_req = run_event_get_running(run_ctx, &monitor_running);
676         if (current_req != NULL) {
677                 if (monitor_running) {
678                         run_event_cancel(current_req);
679                 } else if (strcmp(event_str, "monitor") == 0) {
680                         state->script_list = talloc_zero(
681                                 state, struct run_event_script_list);
682                         if (tevent_req_nomem(state->script_list, req)) {
683                                 return tevent_req_post(req, ev);
684                         }
685                         state->script_list->summary = -ECANCELED;
686                         tevent_req_done(req);
687                         return tevent_req_post(req, ev);
688                 }
689         }
690
691         status = tevent_queue_add(run_event_queue(run_ctx), ev, req,
692                                   run_event_trigger, NULL);
693         if (! status) {
694                 tevent_req_error(req, ENOMEM);
695                 return tevent_req_post(req, ev);
696         }
697
698         return req;
699 }
700
701 static void run_event_cancel(struct tevent_req *req)
702 {
703         struct run_event_state *state = tevent_req_data(
704                 req, struct run_event_state);
705
706         run_event_stop_running(state->run_ctx);
707
708         state->script_list->summary = -ECANCELED;
709         state->cancelled = true;
710
711         TALLOC_FREE(state->script_subreq);
712
713         tevent_req_done(req);
714 }
715
716 static void run_event_trigger(struct tevent_req *req, void *private_data)
717 {
718         struct tevent_req *subreq;
719         struct run_event_state *state = tevent_req_data(
720                 req, struct run_event_state);
721         int ret;
722         bool is_monitor = false;
723
724         D_DEBUG("Running event %s with args \"%s\"\n", state->event_str,
725                 state->arg_str == NULL ? "(null)" : state->arg_str);
726
727         ret = get_script_list(state, run_event_script_dir(state->run_ctx),
728                               &state->script_list);
729         if (ret != 0) {
730                 D_ERR("get_script_list() failed, ret=%d\n", ret);
731                 tevent_req_error(req, ret);
732                 return;
733         }
734
735         /* No scripts */
736         if (state->script_list == NULL ||
737             state->script_list->num_scripts == 0) {
738                 tevent_req_done(req);
739                 return;
740         }
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