ctdb-daemon: Stop using tevent compatibility definitions
[vlendec/samba-autobuild/.git] / ctdb / server / eventscript.c
1 /*
2    event script handling
3
4    Copyright (C) Andrew Tridgell  2007
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 "includes.h"
21 #include <time.h>
22 #include "system/filesys.h"
23 #include "system/wait.h"
24 #include "system/dir.h"
25 #include "system/locale.h"
26 #include "../include/ctdb_private.h"
27 #include "../common/rb_tree.h"
28 #include "lib/util/dlinklist.h"
29 #include "common/system.h"
30
31 static void ctdb_event_script_timeout(struct tevent_context *ev,
32                                       struct tevent_timer *te,
33                                       struct timeval t, void *p);
34
35 /* This is attached to the event script state. */
36 struct event_script_callback {
37         struct event_script_callback *next, *prev;
38         struct ctdb_context *ctdb;
39
40         /* Warning: this can free us! */
41         void (*fn)(struct ctdb_context *, int, void *);
42         void *private_data;
43 };
44
45 struct ctdb_event_script_state {
46         struct ctdb_context *ctdb;
47         struct event_script_callback *callback;
48         pid_t child;
49         int fd[2];
50         enum ctdb_eventscript_call call;
51         const char *options;
52         struct timeval timeout;
53
54         unsigned int current;
55         struct ctdb_scripts_wire *scripts;
56 };
57
58 static struct ctdb_script_wire *get_current_script(struct ctdb_event_script_state *state)
59 {
60         return &state->scripts->scripts[state->current];
61 }
62
63 /* called from ctdb_logging when we have received output on STDERR from
64  * one of the eventscripts
65  */
66 static void log_event_script_output(const char *str, uint16_t len, void *p)
67 {
68         struct ctdb_event_script_state *state
69                 = talloc_get_type(p, struct ctdb_event_script_state);
70         struct ctdb_script_wire *current;
71         unsigned int slen, min;
72
73         /* We may have been aborted to run something else.  Discard */
74         if (state->scripts == NULL) {
75                 return;
76         }
77
78         current = get_current_script(state);
79
80         /* Append, but don't overfill buffer.  It starts zero-filled. */
81         slen = strlen(current->output);
82         min = MIN(len, sizeof(current->output) - slen - 1);
83
84         memcpy(current->output + slen, str, min);
85 }
86
87 int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb,
88                                              uint32_t call_type,
89                                              TDB_DATA *outdata)
90 {
91         if (call_type >= CTDB_EVENT_MAX) {
92                 return -1;
93         }
94
95         if (ctdb->last_status[call_type] == NULL) {
96                 /* If it's never been run, return nothing so they can tell. */
97                 outdata->dsize = 0;
98         } else {
99                 outdata->dsize = talloc_get_size(ctdb->last_status[call_type]);
100                 outdata->dptr  = (uint8_t *)ctdb->last_status[call_type];
101         }
102         return 0;
103 }
104
105 /* To ignore directory entry return 0, else return non-zero */
106 static int script_filter(const struct dirent *de)
107 {
108         int namelen = strlen(de->d_name);
109
110         /* Ignore . and .. */
111         if (namelen < 3) {
112                 return 0;
113         }
114
115         /* Skip temporary files left behind by emacs */
116         if (de->d_name[namelen-1] == '~') {
117                 return 0;
118         }
119
120         /* Filename should start with [0-9][0-9]. */
121         if (!isdigit(de->d_name[0]) || !isdigit(de->d_name[1]) ||
122             de->d_name[2] != '.') {
123                 return 0;
124         }
125
126         if (namelen > MAX_SCRIPT_NAME) {
127                 return 0;
128         }
129
130         return 1;
131 }
132
133 /* Return true if OK, otherwise set errno. */
134 static bool check_executable(const char *dir, const char *name)
135 {
136         char *full;
137         struct stat st;
138
139         full = talloc_asprintf(NULL, "%s/%s", dir, name);
140         if (!full)
141                 return false;
142
143         if (stat(full, &st) != 0) {
144                 DEBUG(DEBUG_ERR,("Could not stat event script %s: %s\n",
145                                  full, strerror(errno)));
146                 talloc_free(full);
147                 return false;
148         }
149
150         if (!(st.st_mode & S_IXUSR)) {
151                 DEBUG(DEBUG_DEBUG,("Event script %s is not executable. Ignoring this event script\n", full));
152                 errno = ENOEXEC;
153                 talloc_free(full);
154                 return false;
155         }
156
157         talloc_free(full);
158         return true;
159 }
160
161 static struct ctdb_scripts_wire *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx)
162 {
163         struct dirent **namelist;
164         struct ctdb_scripts_wire *scripts;
165         int i, count;
166
167         /* scan all directory entries and insert all valid scripts into the
168            tree
169         */
170         count = scandir(ctdb->event_script_dir, &namelist, script_filter, alphasort);
171         if (count == -1) {
172                 DEBUG(DEBUG_CRIT, ("Failed to read event script directory '%s' - %s\n",
173                                    ctdb->event_script_dir, strerror(errno)));
174                 return NULL;
175         }
176
177         /* Overallocates by one, but that's OK */
178         scripts = talloc_zero_size(mem_ctx,
179                                    sizeof(*scripts)
180                                    + sizeof(scripts->scripts[0]) * count);
181         if (scripts == NULL) {
182                 DEBUG(DEBUG_ERR, (__location__ " Failed to allocate scripts\n"));
183                 goto done;
184         }
185         scripts->num_scripts = count;
186
187         for (i = 0; i < count; i++) {
188                 struct ctdb_script_wire *s = &scripts->scripts[i];
189
190                 if (strlcpy(s->name, namelist[i]->d_name, sizeof(s->name)) >=
191                     sizeof(s->name)) {
192                         s->status = -ENAMETOOLONG;
193                         continue;
194                 }
195
196                 s->status = 0;
197                 if (!check_executable(ctdb->event_script_dir,
198                                       namelist[i]->d_name)) {
199                         s->status = -errno;
200                 }
201         }
202
203 done:
204         for (i=0; i<count; i++) {
205                 free(namelist[i]);
206         }
207         free(namelist);
208         return scripts;
209 }
210
211
212 /* There cannot be more than 10 arguments to command helper. */
213 #define MAX_HELPER_ARGS         (10)
214
215 static bool child_helper_args(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
216                               enum ctdb_eventscript_call call,
217                               const char *options,
218                               struct ctdb_script_wire *current, int fd,
219                               int *argc, const char ***argv)
220 {
221         const char **tmp;
222         int n, i;
223         char *t, *saveptr, *opt;
224
225         tmp = talloc_array(mem_ctx, const char *, 10+1);
226         if (tmp == NULL)  goto failed;
227
228         tmp[0] = talloc_asprintf(tmp, "%d", fd);
229         tmp[1] = talloc_asprintf(tmp, "%s/%s", ctdb->event_script_dir, current->name);
230         tmp[2] = talloc_asprintf(tmp, "%s", ctdb_eventscript_call_names[call]);
231         n = 3;
232
233         /* Split options into individual arguments */
234         opt = talloc_strdup(mem_ctx, options);
235         if (opt == NULL) {
236                 goto failed;
237         }
238
239         t = strtok_r(opt, " ", &saveptr);
240         while (t != NULL) {
241                 tmp[n++] = talloc_strdup(tmp, t);
242                 if (n > MAX_HELPER_ARGS) {
243                         goto args_failed;
244                 }
245                 t = strtok_r(NULL, " ", &saveptr);
246         }
247
248         for (i=0; i<n; i++) {
249                 if (tmp[i] == NULL) {
250                         goto failed;
251                 }
252         }
253
254         /* Last argument should be NULL */
255         tmp[n++] = NULL;
256
257         *argc = n;
258         *argv = tmp;
259         return true;
260
261
262 args_failed:
263         DEBUG(DEBUG_ERR, (__location__ " too many arguments '%s' to eventscript '%s'\n",
264                           options, ctdb_eventscript_call_names[call]));
265
266 failed:
267         if (tmp) {
268                 talloc_free(tmp);
269         }
270         return false;
271
272 }
273
274 static void ctdb_event_script_handler(struct tevent_context *ev,
275                                       struct tevent_fd *fde,
276                                       uint16_t flags, void *p);
277
278 static char helper_prog[PATH_MAX+1] = "";
279
280 static int fork_child_for_script(struct ctdb_context *ctdb,
281                                  struct ctdb_event_script_state *state)
282 {
283         int r;
284         struct tevent_fd *fde;
285         struct ctdb_script_wire *current = get_current_script(state);
286         int argc;
287         const char **argv;
288
289         if (!ctdb_set_helper("event helper", helper_prog, sizeof(helper_prog),
290                              "CTDB_EVENT_HELPER",
291                              CTDB_HELPER_BINDIR, "ctdb_event_helper")) {
292                 ctdb_die(ctdb, __location__
293                          " Unable to set event helper\n");
294         }
295
296         current->start = timeval_current();
297
298         r = pipe(state->fd);
299         if (r != 0) {
300                 DEBUG(DEBUG_ERR, (__location__ " pipe failed for child eventscript process\n"));
301                 return -errno;
302         }
303
304         /* Arguments for helper */
305         if (!child_helper_args(state, ctdb, state->call, state->options, current,
306                                state->fd[1], &argc, &argv)) {
307                 DEBUG(DEBUG_ERR, (__location__ " failed to create arguments for eventscript helper\n"));
308                 r = -ENOMEM;
309                 close(state->fd[0]);
310                 close(state->fd[1]);
311                 return r;
312         }
313
314         if (!ctdb_vfork_with_logging(state, ctdb, current->name,
315                                      helper_prog, argc, argv,
316                                      log_event_script_output,
317                                      state, &state->child)) {
318                 talloc_free(argv);
319                 r = -errno;
320                 close(state->fd[0]);
321                 close(state->fd[1]);
322                 return r;
323         }
324
325         talloc_free(argv);
326
327         close(state->fd[1]);
328         set_close_on_exec(state->fd[0]);
329
330         /* Set ourselves up to be called when that's done. */
331         fde = tevent_add_fd(ctdb->ev, state, state->fd[0], TEVENT_FD_READ,
332                             ctdb_event_script_handler, state);
333         tevent_fd_set_auto_close(fde);
334
335         return 0;
336 }
337
338 /*
339  Summarize status of this run of scripts.
340  */
341 static int script_status(struct ctdb_scripts_wire *scripts)
342 {
343         unsigned int i;
344
345         for (i = 0; i < scripts->num_scripts; i++) {
346                 switch (scripts->scripts[i].status) {
347                 case -ENAMETOOLONG:
348                 case -ENOENT:
349                 case -ENOEXEC:
350                         /* Disabled or missing; that's OK. */
351                         break;
352                 case 0:
353                         /* No problem. */
354                         break;
355                 default:
356                         return scripts->scripts[i].status;
357                 }
358         }
359
360         /* All OK! */
361         return 0;
362 }
363
364 /* called when child is finished */
365 static void ctdb_event_script_handler(struct tevent_context *ev,
366                                       struct tevent_fd *fde,
367                                       uint16_t flags, void *p)
368 {
369         struct ctdb_event_script_state *state =
370                 talloc_get_type(p, struct ctdb_event_script_state);
371         struct ctdb_script_wire *current = get_current_script(state);
372         struct ctdb_context *ctdb = state->ctdb;
373         int r, status;
374
375         if (ctdb == NULL) {
376                 DEBUG(DEBUG_ERR,("Eventscript finished but ctdb is NULL\n"));
377                 return;
378         }
379
380         r = sys_read(state->fd[0], &current->status, sizeof(current->status));
381         if (r < 0) {
382                 current->status = -errno;
383         } else if (r == 0) {
384                 current->status = -EINTR;
385         } else if (r != sizeof(current->status)) {
386                 current->status = -EIO;
387         }
388
389         current->finished = timeval_current();
390         /* valgrind gets overloaded if we run next script as it's still doing
391          * post-execution analysis, so kill finished child here. */
392         if (ctdb->valgrinding) {
393                 ctdb_kill(ctdb, state->child, SIGKILL);
394         }
395
396         state->child = 0;
397
398         status = script_status(state->scripts);
399
400         /* Aborted or finished all scripts?  We're done. */
401         if (status != 0 || state->current+1 == state->scripts->num_scripts) {
402                 if (status != 0) {
403                         DEBUG(DEBUG_INFO,
404                               ("Eventscript %s %s finished with state %d\n",
405                                ctdb_eventscript_call_names[state->call],
406                                state->options, status));
407                 }
408
409                 ctdb->event_script_timeouts = 0;
410                 talloc_free(state);
411                 return;
412         }
413
414         /* Forget about that old fd. */
415         talloc_free(fde);
416
417         /* Next script! */
418         state->current++;
419         current++;
420         current->status = fork_child_for_script(ctdb, state);
421         if (current->status != 0) {
422                 /* This calls the callback. */
423                 talloc_free(state);
424         }
425 }
426
427 struct debug_hung_script_state {
428         struct ctdb_context *ctdb;
429         pid_t child;
430         enum ctdb_eventscript_call call;
431 };
432
433 static int debug_hung_script_state_destructor(struct debug_hung_script_state *state)
434 {
435         if (state->child) {
436                 ctdb_kill(state->ctdb, state->child, SIGKILL);
437         }
438         return 0;
439 }
440
441 static void debug_hung_script_timeout(struct tevent_context *ev, struct tevent_timer *te,
442                                       struct timeval t, void *p)
443 {
444         struct debug_hung_script_state *state =
445                 talloc_get_type(p, struct debug_hung_script_state);
446
447         talloc_free(state);
448 }
449
450 static void debug_hung_script_done(struct tevent_context *ev, struct tevent_fd *fde,
451                                    uint16_t flags, void *p)
452 {
453         struct debug_hung_script_state *state =
454                 talloc_get_type(p, struct debug_hung_script_state);
455
456         talloc_free(state);
457 }
458
459 static void ctdb_run_debug_hung_script(struct ctdb_context *ctdb, struct debug_hung_script_state *state)
460 {
461         pid_t pid;
462         const char * debug_hung_script = CTDB_ETCDIR "/debug-hung-script.sh";
463         int fd[2];
464         struct tevent_timer *ttimer;
465         struct tevent_fd *tfd;
466         const char **argv;
467         int i;
468
469         if (pipe(fd) < 0) {
470                 DEBUG(DEBUG_ERR,("Failed to create pipe fd for debug hung script\n"));
471                 return;
472         }
473
474         if (getenv("CTDB_DEBUG_HUNG_SCRIPT") != NULL) {
475                 debug_hung_script = getenv("CTDB_DEBUG_HUNG_SCRIPT");
476         }
477
478         argv = talloc_array(state, const char *, 5);
479
480         argv[0] = talloc_asprintf(argv, "%d", fd[1]);
481         argv[1] = talloc_strdup(argv, debug_hung_script);
482         argv[2] = talloc_asprintf(argv, "%d", state->child);
483         argv[3] = talloc_strdup(argv, ctdb_eventscript_call_names[state->call]);
484         argv[4] = NULL;
485
486         for (i=0; i<4; i++) {
487                 if (argv[i] == NULL) {
488                         close(fd[0]);
489                         close(fd[1]);
490                         talloc_free(argv);
491                         return;
492                 }
493         }
494
495
496         if (!ctdb_vfork_with_logging(state, ctdb, "Hung-script",
497                                      helper_prog, 5, argv, NULL, NULL, &pid)) {
498                 DEBUG(DEBUG_ERR,("Failed to fork a child to track hung event script\n"));
499                 talloc_free(argv);
500                 close(fd[0]);
501                 close(fd[1]);
502                 return;
503         }
504
505         talloc_free(argv);
506         close(fd[1]);
507
508         ttimer = tevent_add_timer(ctdb->ev, state,
509                                   timeval_current_ofs(ctdb->tunable.script_timeout, 0),
510                                   debug_hung_script_timeout, state);
511         if (ttimer == NULL) {
512                 close(fd[0]);
513                 return;
514         }
515
516         tfd = tevent_add_fd(ctdb->ev, state, fd[0], TEVENT_FD_READ,
517                             debug_hung_script_done, state);
518         if (tfd == NULL) {
519                 talloc_free(ttimer);
520                 close(fd[0]);
521                 return;
522         }
523         tevent_fd_set_auto_close(tfd);
524 }
525
526 /* called when child times out */
527 static void ctdb_event_script_timeout(struct tevent_context *ev,
528                                       struct tevent_timer *te,
529                                       struct timeval t, void *p)
530 {
531         struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
532         struct ctdb_context *ctdb = state->ctdb;
533         struct ctdb_script_wire *current = get_current_script(state);
534         struct debug_hung_script_state *debug_state;
535
536         DEBUG(DEBUG_ERR,("Event script '%s %s %s' timed out after %.1fs, count: %u, pid: %d\n",
537                          current->name, ctdb_eventscript_call_names[state->call], state->options,
538                          timeval_elapsed(&current->start),
539                          ctdb->event_script_timeouts, state->child));
540
541         /* ignore timeouts for these events */
542         switch (state->call) {
543         case CTDB_EVENT_START_RECOVERY:
544         case CTDB_EVENT_RECOVERED:
545         case CTDB_EVENT_TAKE_IP:
546         case CTDB_EVENT_RELEASE_IP:
547                 state->scripts->scripts[state->current].status = 0;
548                 DEBUG(DEBUG_ERR,("Ignoring hung script for %s call %d\n", state->options, state->call));
549                 break;
550         default:
551                 state->scripts->scripts[state->current].status = -ETIME;
552         }
553
554         debug_state = talloc_zero(ctdb, struct debug_hung_script_state);
555         if (debug_state == NULL) {
556                 talloc_free(state);
557                 return;
558         }
559
560         /* Save information useful for running debug hung script, so
561          * eventscript state can be freed.
562          */
563         debug_state->ctdb = ctdb;
564         debug_state->child = state->child;
565         debug_state->call = state->call;
566
567         /* This destructor will actually kill the hung event script */
568         talloc_set_destructor(debug_state, debug_hung_script_state_destructor);
569
570         state->child = 0;
571         talloc_free(state);
572
573         ctdb_run_debug_hung_script(ctdb, debug_state);
574 }
575
576 /*
577   destroy an event script: kill it if ->child != 0.
578  */
579 static int event_script_destructor(struct ctdb_event_script_state *state)
580 {
581         int status;
582         struct event_script_callback *callback;
583
584         if (state->child) {
585                 DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
586
587                 if (ctdb_kill(state->ctdb, state->child, SIGTERM) != 0) {
588                         DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
589                 }
590         }
591
592         /* If we were the current monitor, we no longer are. */
593         if (state->ctdb->current_monitor == state) {
594                 state->ctdb->current_monitor = NULL;
595         }
596
597         /* Save our scripts as the last executed status, if we have them.
598          * See ctdb_event_script_callback_v where we abort monitor event. */
599         if (state->scripts) {
600                 talloc_free(state->ctdb->last_status[state->call]);
601                 state->ctdb->last_status[state->call] = state->scripts;
602                 if (state->current < state->ctdb->last_status[state->call]->num_scripts) {
603                         state->ctdb->last_status[state->call]->num_scripts = state->current+1;
604                 }
605         }
606
607         /* Use last status as result, or "OK" if none. */
608         if (state->ctdb->last_status[state->call]) {
609                 status = script_status(state->ctdb->last_status[state->call]);
610         } else {
611                 status = 0;
612         }
613
614         state->ctdb->active_events--;
615         if (state->ctdb->active_events < 0) {
616                 ctdb_fatal(state->ctdb, "Active events < 0");
617         }
618
619         /* This is allowed to free us; talloc will prevent double free anyway,
620          * but beware if you call this outside the destructor!
621          * the callback hangs off a different context so we walk the list
622          * of "active" callbacks until we find the one state points to.
623          * if we cant find it it means the callback has been removed.
624          */
625         for (callback = state->ctdb->script_callbacks; callback != NULL; callback = callback->next) {
626                 if (callback == state->callback) {
627                         break;
628                 }
629         }
630
631         state->callback = NULL;
632
633         if (callback) {
634                 /* Make sure destructor doesn't free itself! */
635                 talloc_steal(NULL, callback);
636                 callback->fn(state->ctdb, status, callback->private_data);
637                 talloc_free(callback);
638         }
639
640         return 0;
641 }
642
643 static unsigned int count_words(const char *options)
644 {
645         unsigned int words = 0;
646
647         options += strspn(options, " \t");
648         while (*options) {
649                 words++;
650                 options += strcspn(options, " \t");
651                 options += strspn(options, " \t");
652         }
653         return words;
654 }
655
656 static bool check_options(enum ctdb_eventscript_call call, const char *options)
657 {
658         switch (call) {
659         /* These all take no arguments. */
660         case CTDB_EVENT_INIT:
661         case CTDB_EVENT_SETUP:
662         case CTDB_EVENT_STARTUP:
663         case CTDB_EVENT_START_RECOVERY:
664         case CTDB_EVENT_RECOVERED:
665         case CTDB_EVENT_MONITOR:
666         case CTDB_EVENT_SHUTDOWN:
667         case CTDB_EVENT_IPREALLOCATED:
668                 return count_words(options) == 0;
669
670         case CTDB_EVENT_TAKE_IP: /* interface, IP address, netmask bits. */
671         case CTDB_EVENT_RELEASE_IP:
672                 return count_words(options) == 3;
673
674         case CTDB_EVENT_UPDATE_IP: /* old interface, new interface, IP address, netmask bits. */
675                 return count_words(options) == 4;
676
677         default:
678                 DEBUG(DEBUG_ERR,(__location__ "Unknown ctdb_eventscript_call %u\n", call));
679                 return false;
680         }
681 }
682
683 static int remove_callback(struct event_script_callback *callback)
684 {
685         DLIST_REMOVE(callback->ctdb->script_callbacks, callback);
686         return 0;
687 }
688
689 /*
690   run the event script in the background, calling the callback when
691   finished
692  */
693 static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
694                                         const void *mem_ctx,
695                                         void (*callback)(struct ctdb_context *, int, void *),
696                                         void *private_data,
697                                         enum ctdb_eventscript_call call,
698                                         const char *fmt, va_list ap)
699 {
700         struct ctdb_event_script_state *state;
701
702         if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
703                 /* we guarantee that only some specifically allowed event scripts are run
704                    while in recovery */
705                 const enum ctdb_eventscript_call allowed_calls[] = {
706                         CTDB_EVENT_INIT,
707                         CTDB_EVENT_SETUP,
708                         CTDB_EVENT_START_RECOVERY,
709                         CTDB_EVENT_SHUTDOWN,
710                         CTDB_EVENT_RELEASE_IP,
711                         CTDB_EVENT_IPREALLOCATED,
712                 };
713                 int i;
714                 for (i=0;i<ARRAY_SIZE(allowed_calls);i++) {
715                         if (call == allowed_calls[i]) break;
716                 }
717                 if (i == ARRAY_SIZE(allowed_calls)) {
718                         DEBUG(DEBUG_ERR,("Refusing to run event scripts call '%s' while in recovery\n",
719                                  ctdb_eventscript_call_names[call]));
720                         return -1;
721                 }
722         }
723
724         /* Do not run new monitor events if some event is already
725          * running, unless the running event is a monitor event, in
726          * which case running a new one should cancel the old one. */
727         if (call == CTDB_EVENT_MONITOR &&
728             ctdb->active_events > 0 &&
729             ctdb->current_monitor == NULL) {
730                 if (callback != NULL) {
731                         callback(ctdb, -ECANCELED, private_data);
732                 }
733                 return 0;
734         }
735
736         /* Kill off any running monitor events to run this event. */
737         if (ctdb->current_monitor) {
738                 struct ctdb_event_script_state *ms = talloc_get_type(ctdb->current_monitor, struct ctdb_event_script_state);
739
740                 /* Cancel current monitor callback state only if monitoring
741                  * context ctdb->monitor->monitor_context has not been freed */
742                 if (ms->callback != NULL && !ctdb_stopped_monitoring(ctdb)) {
743                         ms->callback->fn(ctdb, -ECANCELED, ms->callback->private_data);
744                         talloc_free(ms->callback);
745                 }
746
747                 /* Discard script status so we don't save to last_status */
748                 talloc_free(ctdb->current_monitor->scripts);
749                 ctdb->current_monitor->scripts = NULL;
750                 talloc_free(ctdb->current_monitor);
751                 ctdb->current_monitor = NULL;
752         }
753
754         state = talloc(ctdb->event_script_ctx, struct ctdb_event_script_state);
755         CTDB_NO_MEMORY(ctdb, state);
756
757         /* The callback isn't done if the context is freed. */
758         state->callback = talloc(mem_ctx, struct event_script_callback);
759         CTDB_NO_MEMORY(ctdb, state->callback);
760         DLIST_ADD(ctdb->script_callbacks, state->callback);
761         talloc_set_destructor(state->callback, remove_callback);
762         state->callback->ctdb         = ctdb;
763         state->callback->fn           = callback;
764         state->callback->private_data = private_data;
765
766         state->ctdb = ctdb;
767         state->call = call;
768         state->options = talloc_vasprintf(state, fmt, ap);
769         state->timeout = timeval_set(ctdb->tunable.script_timeout, 0);
770         state->scripts = NULL;
771         if (state->options == NULL) {
772                 DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
773                 talloc_free(state);
774                 return -1;
775         }
776         if (!check_options(state->call, state->options)) {
777                 DEBUG(DEBUG_ERR, ("Bad eventscript options '%s' for '%s'\n",
778                                   state->options,
779                                   ctdb_eventscript_call_names[state->call]));
780                 talloc_free(state);
781                 return -1;
782         }
783
784         DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s %s\n",
785                           ctdb_eventscript_call_names[state->call],
786                           state->options));
787
788         /* This is not a child of state, since we save it in destructor. */
789         state->scripts = ctdb_get_script_list(ctdb, ctdb);
790         if (state->scripts == NULL) {
791                 talloc_free(state);
792                 return -1;
793         }
794         state->current = 0;
795         state->child = 0;
796
797         if (call == CTDB_EVENT_MONITOR) {
798                 ctdb->current_monitor = state;
799         }
800
801         talloc_set_destructor(state, event_script_destructor);
802
803         ctdb->active_events++;
804
805         /* Nothing to do? */
806         if (state->scripts->num_scripts == 0) {
807                 callback(ctdb, 0, private_data);
808                 talloc_free(state);
809                 return 0;
810         }
811
812         state->scripts->scripts[0].status = fork_child_for_script(ctdb, state);
813         if (state->scripts->scripts[0].status != 0) {
814                 /* Callback is called from destructor, with fail result. */
815                 talloc_free(state);
816                 return 0;
817         }
818
819         if (!timeval_is_zero(&state->timeout)) {
820                 tevent_add_timer(ctdb->ev, state,
821                                  timeval_current_ofs(state->timeout.tv_sec,
822                                                      state->timeout.tv_usec),
823                                  ctdb_event_script_timeout, state);
824         } else {
825                 DEBUG(DEBUG_ERR, (__location__ " eventscript %s %s called with no timeout\n",
826                                   ctdb_eventscript_call_names[state->call],
827                                   state->options));
828         }
829
830         return 0;
831 }
832
833
834 /*
835   run the event script in the background, calling the callback when
836   finished.  If mem_ctx is freed, callback will never be called.
837  */
838 int ctdb_event_script_callback(struct ctdb_context *ctdb,
839                                TALLOC_CTX *mem_ctx,
840                                void (*callback)(struct ctdb_context *, int, void *),
841                                void *private_data,
842                                enum ctdb_eventscript_call call,
843                                const char *fmt, ...)
844 {
845         va_list ap;
846         int ret;
847
848         va_start(ap, fmt);
849         ret = ctdb_event_script_callback_v(ctdb, mem_ctx, callback, private_data, call, fmt, ap);
850         va_end(ap);
851
852         return ret;
853 }
854
855
856 struct callback_status {
857         bool done;
858         int status;
859 };
860
861 /*
862   called when ctdb_event_script() finishes
863  */
864 static void event_script_callback(struct ctdb_context *ctdb, int status, void *private_data)
865 {
866         struct callback_status *s = (struct callback_status *)private_data;
867         s->done = true;
868         s->status = status;
869 }
870
871 /*
872   run the event script, waiting for it to complete. Used when the caller
873   doesn't want to continue till the event script has finished.
874  */
875 int ctdb_event_script_args(struct ctdb_context *ctdb, enum ctdb_eventscript_call call,
876                            const char *fmt, ...)
877 {
878         va_list ap;
879         int ret;
880         struct callback_status status = {
881                 .status = -1,
882                 .done = false,
883         };
884
885         va_start(ap, fmt);
886         ret = ctdb_event_script_callback_v(ctdb, ctdb,
887                         event_script_callback, &status, call, fmt, ap);
888         va_end(ap);
889         if (ret != 0) {
890                 return ret;
891         }
892
893         while (status.done == false && tevent_loop_once(ctdb->ev) == 0) /* noop */;
894
895         if (status.status == -ETIME) {
896                 DEBUG(DEBUG_ERR, (__location__ " eventscript for '%s' timedout."
897                                   " Immediately banning ourself for %d seconds\n",
898                                   ctdb_eventscript_call_names[call],
899                                   ctdb->tunable.recovery_ban_period));
900
901                 /* Don't ban self if CTDB is starting up or shutting down */
902                 if (call != CTDB_EVENT_INIT && call != CTDB_EVENT_SHUTDOWN) {
903                         ctdb_ban_self(ctdb);
904                 }
905         }
906
907         return status.status;
908 }
909
910 int ctdb_event_script(struct ctdb_context *ctdb, enum ctdb_eventscript_call call)
911 {
912         /* GCC complains about empty format string, so use %s and "". */
913         return ctdb_event_script_args(ctdb, call, "%s", "");
914 }
915
916 struct eventscript_callback_state {
917         struct ctdb_req_control *c;
918 };
919
920 /*
921   called when a forced eventscript run has finished
922  */
923 static void run_eventscripts_callback(struct ctdb_context *ctdb, int status,
924                                  void *private_data)
925 {
926         const char *errmsg = NULL;
927
928         struct eventscript_callback_state *state =
929                 talloc_get_type(private_data, struct eventscript_callback_state);
930
931         if (status != 0) {
932                 if (status == -ECANCELED) {
933                         DEBUG(DEBUG_WARNING,
934                               (__location__ " Eventscript cancelled\n"));
935                         errmsg = "cancelled";
936                 } else {
937                         DEBUG(DEBUG_ERR,
938                               (__location__ " Failed to run eventscripts\n"));
939                 }
940         }
941
942         ctdb_request_control_reply(ctdb, state->c, NULL, status, errmsg);
943         /* This will free the struct ctdb_event_script_state we are in! */
944         talloc_free(state);
945         return;
946 }
947
948
949 /* Returns rest of string, or NULL if no match. */
950 static const char *get_call(const char *p, enum ctdb_eventscript_call *call)
951 {
952         unsigned int len;
953
954         /* Skip any initial whitespace. */
955         p += strspn(p, " \t");
956
957         /* See if we match any. */
958         for (*call = 0; *call < CTDB_EVENT_MAX; (*call)++) {
959                 len = strlen(ctdb_eventscript_call_names[*call]);
960                 if (strncmp(p, ctdb_eventscript_call_names[*call], len) == 0) {
961                         /* If end of string or whitespace, we're done. */
962                         if (strcspn(p + len, " \t") == 0) {
963                                 return p + len;
964                         }
965                 }
966         }
967         return NULL;
968 }
969
970 /*
971   A control to force running of the eventscripts from the ctdb client tool
972 */
973 int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
974                 struct ctdb_req_control *c,
975                 TDB_DATA indata, bool *async_reply)
976 {
977         int ret;
978         struct eventscript_callback_state *state;
979         const char *options;
980         enum ctdb_eventscript_call call;
981
982         /* Figure out what call they want. */
983         options = get_call((const char *)indata.dptr, &call);
984         if (!options) {
985                 DEBUG(DEBUG_ERR, (__location__ " Invalid event name \"%s\"\n", (const char *)indata.dptr));
986                 return -1;
987         }
988
989         if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
990                 DEBUG(DEBUG_ERR, (__location__ " Aborted running eventscript \"%s\" while in RECOVERY mode\n", indata.dptr));
991                 return -1;
992         }
993
994         state = talloc(ctdb->event_script_ctx, struct eventscript_callback_state);
995         CTDB_NO_MEMORY(ctdb, state);
996
997         state->c = talloc_steal(state, c);
998
999         DEBUG(DEBUG_NOTICE,("Running eventscripts with arguments %s\n", indata.dptr));
1000
1001         ret = ctdb_event_script_callback(ctdb,
1002                          ctdb, run_eventscripts_callback, state,
1003                          call, "%s", options);
1004
1005         if (ret != 0) {
1006                 DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
1007                 talloc_free(state);
1008                 return -1;
1009         }
1010
1011         /* tell ctdb_control.c that we will be replying asynchronously */
1012         *async_reply = true;
1013
1014         return 0;
1015 }
1016
1017
1018
1019 int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1020 {
1021         const char *script;
1022         struct stat st;
1023         char *filename;
1024         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1025
1026         script = (char *)indata.dptr;
1027         if (indata.dsize == 0) {
1028                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1029                 talloc_free(tmp_ctx);
1030                 return -1;
1031         }
1032         if (indata.dptr[indata.dsize - 1] != '\0') {
1033                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1034                 talloc_free(tmp_ctx);
1035                 return -1;
1036         }
1037         if (index(script,'/') != NULL) {
1038                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script));
1039                 talloc_free(tmp_ctx);
1040                 return -1;
1041         }
1042
1043
1044         if (stat(ctdb->event_script_dir, &st) != 0 &&
1045             errno == ENOENT) {
1046                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1047                 talloc_free(tmp_ctx);
1048                 return -1;
1049         }
1050
1051
1052         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1053         if (filename == NULL) {
1054                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1055                 talloc_free(tmp_ctx);
1056                 return -1;
1057         }
1058
1059         if (stat(filename, &st) != 0) {
1060                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename));
1061                 talloc_free(tmp_ctx);
1062                 return -1;
1063         }
1064
1065         if (chmod(filename, st.st_mode | S_IXUSR) == -1) {
1066                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename));
1067                 talloc_free(tmp_ctx);
1068                 return -1;
1069         }
1070
1071         talloc_free(tmp_ctx);
1072         return 0;
1073 }
1074
1075 int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1076 {
1077         const char *script;
1078         struct stat st;
1079         char *filename;
1080         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1081
1082         script = (char *)indata.dptr;
1083         if (indata.dsize == 0) {
1084                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1085                 talloc_free(tmp_ctx);
1086                 return -1;
1087         }
1088         if (indata.dptr[indata.dsize - 1] != '\0') {
1089                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1090                 talloc_free(tmp_ctx);
1091                 return -1;
1092         }
1093         if (index(script,'/') != NULL) {
1094                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script));
1095                 talloc_free(tmp_ctx);
1096                 return -1;
1097         }
1098
1099
1100         if (stat(ctdb->event_script_dir, &st) != 0 &&
1101             errno == ENOENT) {
1102                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1103                 talloc_free(tmp_ctx);
1104                 return -1;
1105         }
1106
1107
1108         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1109         if (filename == NULL) {
1110                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1111                 talloc_free(tmp_ctx);
1112                 return -1;
1113         }
1114
1115         if (stat(filename, &st) != 0) {
1116                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename));
1117                 talloc_free(tmp_ctx);
1118                 return -1;
1119         }
1120
1121         if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) {
1122                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename));
1123                 talloc_free(tmp_ctx);
1124                 return -1;
1125         }
1126
1127         talloc_free(tmp_ctx);
1128         return 0;
1129 }