eventscript: typo cleanups
[sahlberg/ctdb.git] / 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 "lib/events/events.h"
28 #include "../common/rb_tree.h"
29
30 static struct {
31         struct timeval start;
32         const char *script_running;
33 } child_state;
34
35 static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p);
36
37 /*
38   ctdbd sends us a SIGTERM when we should time out the current script
39  */
40 static void sigterm(int sig)
41 {
42         char tbuf[100], buf[200];
43         time_t t;
44
45         DEBUG(DEBUG_ERR,("Timed out running script '%s' after %.1f seconds pid :%d\n", 
46                  child_state.script_running, timeval_elapsed(&child_state.start), getpid()));
47
48         t = time(NULL);
49
50         strftime(tbuf, sizeof(tbuf)-1, "%Y%m%d%H%M%S",  localtime(&t));
51         sprintf(buf, "pstree -p >/tmp/ctdb.event.%s.%d", tbuf, getpid());
52         system(buf);
53
54         DEBUG(DEBUG_ERR,("Logged timedout eventscript : %s\n", buf));
55
56         /* all the child processes will be running in the same process group */
57         kill(-getpgrp(), SIGKILL);
58         _exit(1);
59 }
60
61 struct ctdb_event_script_state {
62         struct ctdb_context *ctdb;
63         pid_t child;
64         /* Warning: this can free us! */
65         void (*callback)(struct ctdb_context *, int, void *);
66         int cb_status;
67         int fd[2];
68         void *private_data;
69         const char *options;
70         struct timeval timeout;
71 };
72
73
74 struct ctdb_monitor_script_status {
75         struct ctdb_monitor_script_status *next;
76         const char *name;
77         struct timeval start;
78         struct timeval finished;
79         int32_t disabled;
80         int32_t status;
81         int32_t timedout;
82         char *output;
83 };
84
85 struct ctdb_monitor_script_status_ctx {
86         struct ctdb_monitor_script_status *scripts;
87 };
88
89 /* called from ctdb_logging when we have received output on STDERR from
90  * one of the eventscripts
91  */
92 int ctdb_log_event_script_output(struct ctdb_context *ctdb, char *str, uint16_t len)
93 {
94         struct ctdb_monitor_script_status *script;
95
96         if (ctdb->current_monitor_status_ctx == NULL) {
97                 return -1;
98         }
99
100         script = ctdb->current_monitor_status_ctx->scripts;
101         if (script == NULL) {
102                 return -1;
103         }
104
105         if (script->output == NULL) {
106                 script->output = talloc_asprintf(script, "%*.*s", len, len, str);
107         } else {
108                 script->output = talloc_asprintf_append(script->output, "%*.*s", len, len, str);
109         }
110
111         return 0;
112 }
113
114 /* called from the event script child process when we are starting a new
115  * monitor event
116  */
117 int32_t ctdb_control_event_script_init(struct ctdb_context *ctdb)
118 {
119         DEBUG(DEBUG_INFO, ("event script init called\n"));
120
121         if (ctdb->current_monitor_status_ctx == NULL) {
122                 DEBUG(DEBUG_ERR,(__location__ " current_monitor_status_ctx is NULL when initing script\n"));
123                 return -1;
124         }
125
126         return 0;
127 }
128
129
130 /* called from the event script child process when we are star running
131  * an eventscript
132  */
133 int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA indata)
134 {
135         const char *name = (const char *)indata.dptr;
136         struct ctdb_monitor_script_status *script;
137
138         DEBUG(DEBUG_INFO, ("event script start called : %s\n", name));
139
140         if (ctdb->current_monitor_status_ctx == NULL) {
141                 DEBUG(DEBUG_ERR,(__location__ " current_monitor_status_ctx is NULL when starting script\n"));
142                 return -1;
143         }
144
145         script = talloc_zero(ctdb->current_monitor_status_ctx, struct ctdb_monitor_script_status);
146         if (script == NULL) {
147                 DEBUG(DEBUG_ERR,(__location__ " Failed to talloc ctdb_monitor_script_status for script %s\n", name));
148                 return -1;
149         }
150
151         script->next  = ctdb->current_monitor_status_ctx->scripts;
152         script->name  = talloc_strdup(script, name);
153         CTDB_NO_MEMORY(ctdb, script->name);
154         script->start = timeval_current();
155         ctdb->current_monitor_status_ctx->scripts = script;
156
157         return 0;
158 }
159
160 /* called from the event script child process when we have finished running
161  * an eventscript
162  */
163 int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indata)
164 {
165         int32_t res = *((int32_t *)indata.dptr);
166         struct ctdb_monitor_script_status *script;
167
168         if (ctdb->current_monitor_status_ctx == NULL) {
169                 DEBUG(DEBUG_ERR,(__location__ " current_monitor_status_ctx is NULL when script finished\n"));
170                 return -1;
171         }
172
173         script = ctdb->current_monitor_status_ctx->scripts;
174         if (script == NULL) {
175                 DEBUG(DEBUG_ERR,(__location__ " script is NULL when the script had finished\n"));
176                 return -1;
177         }
178
179         script->finished = timeval_current();
180         script->status   = res;
181
182         DEBUG(DEBUG_INFO, ("event script stop called for script:%s duration:%.1f status:%d\n", script->name, timeval_elapsed(&script->start), (int)res));
183
184         return 0;
185 }
186
187 /* called from the event script child process when we have a disabled script
188  */
189 int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA indata)
190 {
191         const char *name = (const char *)indata.dptr;
192         struct ctdb_monitor_script_status *script;
193
194         DEBUG(DEBUG_INFO, ("event script disabed called for script %s\n", name));
195
196         if (ctdb->current_monitor_status_ctx == NULL) {
197                 DEBUG(DEBUG_ERR,(__location__ " current_monitor_status_ctx is NULL when script finished\n"));
198                 return -1;
199         }
200
201         script = ctdb->current_monitor_status_ctx->scripts;
202         if (script == NULL) {
203                 DEBUG(DEBUG_ERR,(__location__ " script is NULL when the script had finished\n"));
204                 return -1;
205         }
206
207         script->finished = timeval_current();
208         script->status   = 0;
209         script->disabled = 1;
210
211         return 0;
212 }
213
214 /* called from the event script child process when we have completed a
215  * monitor event
216  */
217 int32_t ctdb_control_event_script_finished(struct ctdb_context *ctdb)
218 {
219         DEBUG(DEBUG_INFO, ("event script finished called\n"));
220
221         if (ctdb->current_monitor_status_ctx == NULL) {
222                 DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when monitoring event finished\n"));
223                 return -1;
224         }
225
226         if (ctdb->last_monitor_status_ctx) {
227                 talloc_free(ctdb->last_monitor_status_ctx);
228                 ctdb->last_monitor_status_ctx = NULL;
229         }
230         ctdb->last_monitor_status_ctx = talloc_steal(ctdb, ctdb->current_monitor_status_ctx);
231         ctdb->current_monitor_status_ctx = NULL;
232
233         return 0;
234 }
235
236 static struct ctdb_monitoring_wire *marshall_monitoring_scripts(TALLOC_CTX *mem_ctx, struct ctdb_monitoring_wire *monitoring_scripts, struct ctdb_monitor_script_status *script)
237 {
238         struct ctdb_monitoring_script_wire script_wire;
239         size_t size;
240
241         if (script == NULL) {
242                 return monitoring_scripts;
243         }
244         monitoring_scripts = marshall_monitoring_scripts(mem_ctx, monitoring_scripts, script->next);
245         if (monitoring_scripts == NULL) {
246                 return NULL;
247         }
248
249         bzero(&script_wire, sizeof(struct ctdb_monitoring_script_wire));
250         strncpy(script_wire.name, script->name, MAX_SCRIPT_NAME);
251         script_wire.start    = script->start;
252         script_wire.finished = script->finished;
253         script_wire.disabled = script->disabled;
254         script_wire.status   = script->status;
255         script_wire.timedout = script->timedout;
256         if (script->output != NULL) {
257                 strncpy(script_wire.output, script->output, MAX_SCRIPT_OUTPUT);
258         }
259
260         size = talloc_get_size(monitoring_scripts);
261         monitoring_scripts = talloc_realloc_size(mem_ctx, monitoring_scripts, size + sizeof(struct ctdb_monitoring_script_wire));
262         if (monitoring_scripts == NULL) {
263                 DEBUG(DEBUG_ERR,(__location__ " Failed to talloc_resize monitoring_scripts blob\n"));
264                 return NULL;
265         }
266
267         memcpy(&monitoring_scripts->scripts[monitoring_scripts->num_scripts], &script_wire, sizeof(script_wire));
268         monitoring_scripts->num_scripts++;
269         
270         return monitoring_scripts;
271 }
272
273 int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb, TDB_DATA *outdata)
274 {
275         struct ctdb_monitor_script_status_ctx *script_status = talloc_get_type(ctdb->last_monitor_status_ctx, struct ctdb_monitor_script_status_ctx);
276         struct ctdb_monitoring_wire *monitoring_scripts;
277
278         if (script_status == NULL) {
279                 DEBUG(DEBUG_ERR,(__location__ " last_monitor_status_ctx is NULL when reading status\n"));
280                 return -1;
281         }
282
283         monitoring_scripts = talloc_size(outdata, offsetof(struct ctdb_monitoring_wire, scripts));
284         if (monitoring_scripts == NULL) {
285                 DEBUG(DEBUG_ERR,(__location__ " failed to talloc monitoring_scripts structure\n"));
286                 return -1;
287         }
288         
289         monitoring_scripts->num_scripts = 0;
290         monitoring_scripts = marshall_monitoring_scripts(outdata, monitoring_scripts, script_status->scripts);
291         if (monitoring_scripts == NULL) {
292                 DEBUG(DEBUG_ERR,(__location__ " Monitoring scritps is NULL. can not return data to client\n"));
293                 return -1;
294         }
295
296         outdata->dsize = talloc_get_size(monitoring_scripts);
297         outdata->dptr  = (uint8_t *)monitoring_scripts;
298
299         return 0;
300 }
301
302 struct ctdb_script_tree_item {
303         const char *name;
304         int32_t is_enabled;
305 };
306
307 struct ctdb_script_list {
308         struct ctdb_script_list *next;
309         const char *name;
310         int32_t is_enabled;
311 };
312
313 static struct ctdb_script_list *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx)
314 {
315         DIR *dir;
316         struct dirent *de;
317         struct stat st;
318         trbt_tree_t *tree;
319         struct ctdb_script_list *head, *tail, *new_item;
320         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
321         struct ctdb_script_tree_item *tree_item;
322         int count;
323
324         /*
325           the service specific event scripts 
326         */
327         if (stat(ctdb->event_script_dir, &st) != 0 && 
328             errno == ENOENT) {
329                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
330                 talloc_free(tmp_ctx);
331                 return NULL;
332         }
333
334         /* create a tree to store all the script names in */
335         tree = trbt_create(tmp_ctx, 0);
336
337         /* scan all directory entries and insert all valid scripts into the 
338            tree
339         */
340         dir = opendir(ctdb->event_script_dir);
341         if (dir == NULL) {
342                 DEBUG(DEBUG_CRIT,("Failed to open event script directory '%s'\n", ctdb->event_script_dir));
343                 talloc_free(tmp_ctx);
344                 return NULL;
345         }
346
347         count = 0;
348         while ((de=readdir(dir)) != NULL) {
349                 int namlen;
350                 unsigned num;
351                 char *str;
352
353                 namlen = strlen(de->d_name);
354
355                 if (namlen < 3) {
356                         continue;
357                 }
358
359                 if (de->d_name[namlen-1] == '~') {
360                         /* skip files emacs left behind */
361                         continue;
362                 }
363
364                 if (de->d_name[2] != '.') {
365                         continue;
366                 }
367
368                 if (sscanf(de->d_name, "%02u.", &num) != 1) {
369                         continue;
370                 }
371
372                 /* Make sure the event script is executable */
373                 str = talloc_asprintf(tree, "%s/%s", ctdb->event_script_dir, de->d_name);
374                 if (stat(str, &st) != 0) {
375                         DEBUG(DEBUG_ERR,("Could not stat event script %s. Ignoring this event script\n", str));
376                         continue;
377                 }
378
379
380                 tree_item = talloc(tree, struct ctdb_script_tree_item);
381                 if (tree_item == NULL) {
382                         DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new tree item\n"));
383                         talloc_free(tmp_ctx);
384                         return NULL;
385                 }
386         
387                 tree_item->is_enabled = 1;
388                 if (!(st.st_mode & S_IXUSR)) {
389                         DEBUG(DEBUG_INFO,("Event script %s is not executable. Ignoring this event script\n", str));
390                         tree_item->is_enabled = 0;
391                 }
392
393                 tree_item->name = talloc_strdup(tree_item, de->d_name);
394                 if (tree_item->name == NULL) {
395                         DEBUG(DEBUG_ERR,(__location__ " Failed to allocate script name.\n"));
396                         talloc_free(tmp_ctx);
397                         return NULL;
398                 }
399
400                 /* store the event script in the tree */
401                 trbt_insert32(tree, (num<<16)|count++, tree_item);
402         }
403         closedir(dir);
404
405
406         head = NULL;
407         tail = NULL;
408
409         /* fetch the scripts from the tree one by one and add them to the linked
410            list
411          */
412         while ((tree_item=trbt_findfirstarray32(tree, 1)) != NULL) {
413
414                 new_item = talloc(tmp_ctx, struct ctdb_script_list);
415                 if (new_item == NULL) {
416                         DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new list item\n"));
417                         talloc_free(tmp_ctx);
418                         return NULL;
419                 }
420
421                 new_item->next = NULL;
422                 new_item->name = talloc_steal(new_item, tree_item->name);
423                 new_item->is_enabled = tree_item->is_enabled;
424
425                 if (head == NULL) {
426                         head = new_item;
427                         tail = new_item;
428                 } else {
429                         tail->next = new_item;
430                         tail = new_item;
431                 }
432
433                 talloc_steal(mem_ctx, new_item);
434
435                 /* remove this script from the tree */
436                 talloc_free(tree_item);
437         }       
438
439         talloc_free(tmp_ctx);
440         return head;
441 }
442
443
444
445 /*
446   Actually run the event script
447   this function is called and run in the context of a forked child
448   which allows it to do blocking calls such as system()
449  */
450 static int ctdb_run_event_script(struct ctdb_context *ctdb, const char *options)
451 {
452         char *cmdstr;
453         int ret;
454         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
455         struct ctdb_script_list *scripts, *current;
456         int is_monitor = 0;
457
458         if (!strcmp(options, "monitor")) {
459                 is_monitor = 1;
460         }
461
462         if (is_monitor == 1) {
463                 /* This is running in the forked child process. At this stage
464                  * we want to switch from being a ctdb daemon into being a
465                  * client and connect to the real local daemon.
466                  */
467                 if (switch_from_server_to_client(ctdb) != 0) {
468                         DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch eventscript child into client mode. shutting down.\n"));
469                         _exit(1);
470                 }
471
472                 if (ctdb_ctrl_event_script_init(ctdb) != 0) {
473                         DEBUG(DEBUG_ERR,(__location__ " Failed to init event script monitoring\n"));
474                         talloc_free(tmp_ctx);
475                         return -1;
476                 }
477         }
478
479         if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
480                 /* we guarantee that only some specifically allowed event scripts are run
481                    while in recovery */
482                 const char *allowed_scripts[] = {"startrecovery", "shutdown", "releaseip", "stopped" };
483                 int i;
484                 for (i=0;i<ARRAY_SIZE(allowed_scripts);i++) {
485                         if (strncmp(options, allowed_scripts[i], strlen(allowed_scripts[i])) == 0) break;
486                 }
487                 if (i == ARRAY_SIZE(allowed_scripts)) {
488                         DEBUG(DEBUG_ERR,("Refusing to run event scripts with option '%s' while in recovery\n",
489                                  options));
490                         talloc_free(tmp_ctx);
491                         return -1;
492                 }
493         }
494
495         if (setpgid(0,0) != 0) {
496                 DEBUG(DEBUG_ERR,("Failed to create process group for event scripts - %s\n",
497                          strerror(errno)));
498                 talloc_free(tmp_ctx);
499                 return -1;              
500         }
501
502         signal(SIGTERM, sigterm);
503
504         child_state.start = timeval_current();
505         child_state.script_running = "startup";
506
507         scripts = ctdb_get_script_list(ctdb, tmp_ctx);
508
509         /* fetch the scripts from the tree one by one and execute
510            them
511          */
512         for (current=scripts; current; current=current->next) {
513                 /* Allow a setting where we run the actual monitor event
514                    from an external source and replace it with
515                    a "status" event that just picks up the actual
516                    status of the event asynchronously.
517                 */
518                 if ((ctdb->tunable.use_status_events_for_monitoring != 0) 
519                 && (!strcmp(options, "monitor"))) {
520                         cmdstr = talloc_asprintf(tmp_ctx, "%s/%s %s", 
521                                         ctdb->event_script_dir,
522                                         current->name, "status");
523                 } else {
524                         cmdstr = talloc_asprintf(tmp_ctx, "%s/%s %s", 
525                                         ctdb->event_script_dir,
526                                         current->name, options);
527                 }
528                 CTDB_NO_MEMORY(ctdb, cmdstr);
529
530                 DEBUG(DEBUG_INFO,("Executing event script %s\n",cmdstr));
531
532                 child_state.start = timeval_current();
533                 child_state.script_running = cmdstr;
534
535                 if (is_monitor == 1) {
536                         if (ctdb_ctrl_event_script_start(ctdb, current->name) != 0) {
537                                 DEBUG(DEBUG_ERR,(__location__ " Failed to start event script monitoring\n"));
538                                 talloc_free(tmp_ctx);
539                                 return -1;
540                         }
541
542                         if (!current->is_enabled) {
543                                 if (ctdb_ctrl_event_script_disabled(ctdb, current->name) != 0) {
544                                         DEBUG(DEBUG_ERR,(__location__ " Failed to report disabled eventscript\n"));
545                                         talloc_free(tmp_ctx);
546                                         return -1;
547                                 }
548                         }
549
550                 }
551
552                 if (!current->is_enabled) {
553                         continue;
554                 }
555
556                 ret = system(cmdstr);
557                 /* if the system() call was successful, translate ret into the
558                    return code from the command
559                 */
560                 if (ret != -1) {
561                         ret = WEXITSTATUS(ret);
562                 }
563                 if (ret == 127) {
564                         ret = 0;
565                         DEBUG(DEBUG_ERR,("Script %s returned status 127. Someone just deleted it?\n", cmdstr));
566                 }
567  
568                 if (is_monitor == 1) {
569                         if (ctdb_ctrl_event_script_stop(ctdb, ret) != 0) {
570                                 DEBUG(DEBUG_ERR,(__location__ " Failed to stop event script monitoring\n"));
571                                 talloc_free(tmp_ctx);
572                                 return -1;
573                         }
574                 }
575
576                 /* return an error if the script failed */
577                 if (ret != 0) {
578                         DEBUG(DEBUG_ERR,("Event script %s failed with error %d\n", cmdstr, ret));
579                         if (is_monitor == 1) {
580                                 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
581                                         DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
582                                         talloc_free(tmp_ctx);
583                                         return -1;
584                                 }
585                         }
586
587                         talloc_free(tmp_ctx);
588                         return ret;
589                 }
590         }
591
592         child_state.start = timeval_current();
593         child_state.script_running = "finished";
594         
595         if (is_monitor == 1) {
596                 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
597                         DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
598                         talloc_free(tmp_ctx);
599                         return -1;
600                 }
601         }
602
603         talloc_free(tmp_ctx);
604         return 0;
605 }
606
607 /* called when child is finished */
608 static void ctdb_event_script_handler(struct event_context *ev, struct fd_event *fde, 
609                                       uint16_t flags, void *p)
610 {
611         struct ctdb_event_script_state *state = 
612                 talloc_get_type(p, struct ctdb_event_script_state);
613         struct ctdb_context *ctdb = state->ctdb;
614
615         if (read(state->fd[0], &state->cb_status, sizeof(state->cb_status)) !=
616             sizeof(state->cb_status)) {
617                 state->cb_status = -2;
618         }
619
620         DEBUG(DEBUG_INFO,(__location__ " Eventscript %s finished with state %d\n", state->options, state->cb_status));
621
622         state->child = 0;
623         ctdb->event_script_timeouts = 0;
624         talloc_free(state);
625 }
626
627 static void ctdb_ban_self(struct ctdb_context *ctdb, uint32_t ban_period)
628 {
629         TDB_DATA data;
630         struct ctdb_ban_time bantime;
631
632         bantime.pnn  = ctdb->pnn;
633         bantime.time = ban_period;
634
635         data.dsize = sizeof(bantime);
636         data.dptr  = (uint8_t *)&bantime;
637
638         ctdb_control_set_ban_state(ctdb, data);
639 }
640
641
642 /* called when child times out */
643 static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, 
644                                       struct timeval t, void *p)
645 {
646         struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
647         struct ctdb_context *ctdb = state->ctdb;
648
649         DEBUG(DEBUG_ERR,("Event script timed out : %s count : %u  pid : %d\n", state->options, ctdb->event_script_timeouts, state->child));
650
651         if (kill(state->child, 0) != 0) {
652                 DEBUG(DEBUG_ERR,("Event script child process already dead, errno %s(%d)\n", strerror(errno), errno));
653                 state->child = 0;
654                 talloc_free(state);
655                 return;
656         }
657
658         if (!strcmp(state->options, "monitor")) {
659                 /* if it is a monitor event, we allow it to "hang" a few times
660                    before we declare it a failure and ban ourself (and make
661                    ourself unhealthy)
662                 */
663                 DEBUG(DEBUG_ERR, (__location__ " eventscript for monitor event timedout.\n"));
664
665                 ctdb->event_script_timeouts++;
666
667                 if (ctdb->event_script_timeouts > ctdb->tunable.script_ban_count) {
668                         DEBUG(DEBUG_ERR, ("Maximum timeout count %u reached for eventscript. Making node unhealthy\n", ctdb->tunable.script_ban_count));
669                         state->cb_status = -ETIME;
670                 } else {
671                         state->cb_status = 0;
672                 }
673         } else if (!strcmp(state->options, "startup")) {
674                 DEBUG(DEBUG_ERR, (__location__ " eventscript for startup event timedout.\n"));
675                 state->cb_status = -1;
676         } else {
677                 /* if it is not a monitor or a startup event we ban ourself
678                    immediately
679                 */
680                 DEBUG(DEBUG_ERR, (__location__ " eventscript for NON-monitor/NON-startup event timedout. Immediately banning ourself for %d seconds\n", ctdb->tunable.recovery_ban_period));
681
682                 ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
683
684                 state->cb_status = -1;
685         }
686
687         if (!strcmp(state->options, "monitor") || !strcmp(state->options, "status")) {
688                 struct ctdb_monitor_script_status *script;
689
690                 if (ctdb->current_monitor_status_ctx == NULL) {
691                         talloc_free(state);
692                         return;
693                 }
694
695                 script = ctdb->current_monitor_status_ctx->scripts;
696                 if (script != NULL) {
697                         script->timedout = 1;
698                 }
699
700                 if (ctdb->last_monitor_status_ctx) {
701                         talloc_free(ctdb->last_monitor_status_ctx);
702                         ctdb->last_monitor_status_ctx = NULL;
703                 }
704                 ctdb->last_monitor_status_ctx = talloc_steal(ctdb, ctdb->current_monitor_status_ctx);
705                 ctdb->current_monitor_status_ctx = NULL;
706         }
707
708         talloc_free(state);
709 }
710
711 /*
712   destroy an event script: kill it if ->child != 0.
713  */
714 static int event_script_destructor(struct ctdb_event_script_state *state)
715 {
716         if (state->child) {
717                 DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
718
719                 if (kill(state->child, SIGTERM) != 0) {
720                         DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
721                 }
722         }
723
724         /* This is allowed to free us; talloc will prevent double free anyway,
725          * but beware if you call this outside the destructor! */
726         if (state->callback) {
727                 state->callback(state->ctdb, state->cb_status, state->private_data);
728         }
729
730         return 0;
731 }
732
733 /*
734   run the event script in the background, calling the callback when 
735   finished
736  */
737 static int ctdb_event_script_callback_v(struct ctdb_context *ctdb, 
738                                         struct timeval timeout,
739                                         void (*callback)(struct ctdb_context *, int, void *),
740                                         void *private_data,
741                                         const char *fmt, va_list ap)
742 {
743         TALLOC_CTX *mem_ctx;
744         struct ctdb_event_script_state *state;
745         int ret;
746
747         if (!strcmp(fmt, "monitor") || !strcmp(fmt, "status")) {
748                 /* if this was a "monitor" or a status event, we recycle the
749                    context to start a new monitor event
750                 */
751                 if (ctdb->monitor_event_script_ctx != NULL) {
752                         talloc_free(ctdb->monitor_event_script_ctx);
753                         ctdb->monitor_event_script_ctx = NULL;
754                 }
755                 ctdb->monitor_event_script_ctx = talloc_new(ctdb);
756                 mem_ctx = ctdb->monitor_event_script_ctx;
757
758                 if (ctdb->current_monitor_status_ctx != NULL) {
759                         talloc_free(ctdb->current_monitor_status_ctx);
760                         ctdb->current_monitor_status_ctx = NULL;
761                 }
762
763                 ctdb->current_monitor_status_ctx = talloc(ctdb->monitor_event_script_ctx, struct ctdb_monitor_script_status_ctx);
764                 ctdb->current_monitor_status_ctx->scripts = NULL;
765         } else {
766                 /* any other script will first terminate any monitor event */
767                 if (ctdb->monitor_event_script_ctx != NULL) {
768                         talloc_free(ctdb->monitor_event_script_ctx);
769                         ctdb->monitor_event_script_ctx = NULL;
770                 }
771                 /* and then use a context common for all non-monitor events */
772                 if (ctdb->other_event_script_ctx != NULL) {
773                         talloc_free(ctdb->other_event_script_ctx);
774                         ctdb->other_event_script_ctx = NULL;
775                 }
776                 ctdb->other_event_script_ctx = talloc_new(ctdb);
777                 mem_ctx = ctdb->other_event_script_ctx;
778         }
779
780         state = talloc(mem_ctx, struct ctdb_event_script_state);
781         CTDB_NO_MEMORY(ctdb, state);
782
783         state->ctdb = ctdb;
784         state->callback = callback;
785         state->private_data = private_data;
786         state->options = talloc_vasprintf(state, fmt, ap);
787         state->timeout = timeout;
788         if (state->options == NULL) {
789                 DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
790                 talloc_free(state);
791                 return -1;
792         }
793
794         DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s\n", state->options));
795         
796         ret = pipe(state->fd);
797         if (ret != 0) {
798                 talloc_free(state);
799                 return -1;
800         }
801
802         state->child = fork();
803
804         if (state->child == (pid_t)-1) {
805                 close(state->fd[0]);
806                 close(state->fd[1]);
807                 talloc_free(state);
808                 return -1;
809         }
810
811         if (state->child == 0) {
812                 int rt;
813
814                 close(state->fd[0]);
815                 set_close_on_exec(state->fd[1]);
816
817                 rt = ctdb_run_event_script(ctdb, state->options);
818                 /* We must be able to write PIPEBUF bytes at least; if this
819                    somehow fails, the read above will be short. */
820                 write(state->fd[1], &rt, sizeof(rt));
821                 close(state->fd[1]);
822                 _exit(rt);
823         }
824
825         close(state->fd[1]);
826         set_close_on_exec(state->fd[0]);
827         talloc_set_destructor(state, event_script_destructor);
828
829         DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child eventscript process\n", state->fd[0]));
830
831         event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
832                      ctdb_event_script_handler, state);
833
834         if (!timeval_is_zero(&state->timeout)) {
835                 event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
836         } else {
837                 DEBUG(DEBUG_ERR, (__location__ " eventscript %s called with no timeout\n", state->options));
838         }
839
840         return 0;
841 }
842
843
844 /*
845   run the event script in the background, calling the callback when 
846   finished
847  */
848 int ctdb_event_script_callback(struct ctdb_context *ctdb, 
849                                struct timeval timeout,
850                                TALLOC_CTX *mem_ctx,
851                                void (*callback)(struct ctdb_context *, int, void *),
852                                void *private_data,
853                                const char *fmt, ...)
854 {
855         va_list ap;
856         int ret;
857
858         va_start(ap, fmt);
859         ret = ctdb_event_script_callback_v(ctdb, timeout, callback, private_data, fmt, ap);
860         va_end(ap);
861
862         return ret;
863 }
864
865
866 struct callback_status {
867         bool done;
868         int status;
869 };
870
871 /*
872   called when ctdb_event_script() finishes
873  */
874 static void event_script_callback(struct ctdb_context *ctdb, int status, void *private_data)
875 {
876         struct callback_status *s = (struct callback_status *)private_data;
877         s->done = true;
878         s->status = status;
879 }
880
881 /*
882   run the event script, waiting for it to complete. Used when the caller
883   doesn't want to continue till the event script has finished.
884  */
885 int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
886 {
887         va_list ap;
888         int ret;
889         struct callback_status status;
890
891         va_start(ap, fmt);
892         ret = ctdb_event_script_callback_v(ctdb, 
893                         timeval_set(ctdb->tunable.script_timeout, 0),
894                         event_script_callback, &status, fmt, ap);
895         va_end(ap);
896
897         if (ret != 0) {
898                 return ret;
899         }
900
901         status.status = -1;
902         status.done = false;
903
904         while (status.done == false && event_loop_once(ctdb->ev) == 0) /* noop */;
905
906         return status.status;
907 }
908
909
910 struct eventscript_callback_state {
911         struct ctdb_req_control *c;
912 };
913
914 /*
915   called when a forced eventscript finishes
916  */
917 static void run_eventscripts_callback(struct ctdb_context *ctdb, int status, 
918                                  void *private_data)
919 {
920         struct eventscript_callback_state *state = 
921                 talloc_get_type(private_data, struct eventscript_callback_state);
922
923         ctdb_enable_monitoring(ctdb);
924
925         if (status != 0) {
926                 DEBUG(DEBUG_ERR,(__location__ " Failed to forcibly run eventscripts\n"));
927         }
928
929         ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
930         /* This will free the struct ctdb_event_script_state we are in! */
931         talloc_free(state);
932         return;
933 }
934
935
936 /*
937   A control to force running of the eventscripts from the ctdb client tool
938 */
939 int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
940                 struct ctdb_req_control *c,
941                 TDB_DATA indata, bool *async_reply)
942 {
943         int ret;
944         struct eventscript_callback_state *state;
945
946         if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
947                 DEBUG(DEBUG_ERR, (__location__ " Aborted running eventscript \"%s\" while in RECOVERY mode\n", indata.dptr));
948                 return -1;
949         }
950
951         state = talloc(ctdb->other_event_script_ctx, struct eventscript_callback_state);
952         CTDB_NO_MEMORY(ctdb, state);
953
954         state->c = talloc_steal(state, c);
955
956         DEBUG(DEBUG_NOTICE,("Forced running of eventscripts with arguments %s\n", indata.dptr));
957
958         ctdb_disable_monitoring(ctdb);
959
960         ret = ctdb_event_script_callback(ctdb, 
961                          timeval_set(ctdb->tunable.script_timeout, 0),
962                          state, run_eventscripts_callback, state,
963                          "%s", (const char *)indata.dptr);
964
965         if (ret != 0) {
966                 ctdb_enable_monitoring(ctdb);
967                 DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
968                 talloc_free(state);
969                 return -1;
970         }
971
972         /* tell ctdb_control.c that we will be replying asynchronously */
973         *async_reply = true;
974
975         return 0;
976 }
977
978
979
980 int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata)
981 {
982         const char *script;
983         struct stat st;
984         char *filename;
985         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
986
987         script = (char *)indata.dptr;
988         if (indata.dsize == 0) {
989                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
990                 talloc_free(tmp_ctx);
991                 return -1;
992         }
993         if (indata.dptr[indata.dsize - 1] != '\0') {
994                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
995                 talloc_free(tmp_ctx);
996                 return -1;
997         }
998         if (index(script,'/') != NULL) {
999                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script));
1000                 talloc_free(tmp_ctx);
1001                 return -1;
1002         }
1003
1004
1005         if (stat(ctdb->event_script_dir, &st) != 0 && 
1006             errno == ENOENT) {
1007                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1008                 talloc_free(tmp_ctx);
1009                 return -1;
1010         }
1011
1012
1013         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1014         if (filename == NULL) {
1015                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1016                 talloc_free(tmp_ctx);
1017                 return -1;
1018         }
1019
1020         if (stat(filename, &st) != 0) {
1021                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename));
1022                 talloc_free(tmp_ctx);
1023                 return -1;
1024         }
1025
1026         if (chmod(filename, st.st_mode | S_IXUSR) == -1) {
1027                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename));
1028                 talloc_free(tmp_ctx);
1029                 return -1;
1030         }
1031
1032         talloc_free(tmp_ctx);
1033         return 0;
1034 }
1035
1036 int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1037 {
1038         const char *script;
1039         struct stat st;
1040         char *filename;
1041         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1042
1043         script = (char *)indata.dptr;
1044         if (indata.dsize == 0) {
1045                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1046                 talloc_free(tmp_ctx);
1047                 return -1;
1048         }
1049         if (indata.dptr[indata.dsize - 1] != '\0') {
1050                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1051                 talloc_free(tmp_ctx);
1052                 return -1;
1053         }
1054         if (index(script,'/') != NULL) {
1055                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script));
1056                 talloc_free(tmp_ctx);
1057                 return -1;
1058         }
1059
1060
1061         if (stat(ctdb->event_script_dir, &st) != 0 && 
1062             errno == ENOENT) {
1063                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1064                 talloc_free(tmp_ctx);
1065                 return -1;
1066         }
1067
1068
1069         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1070         if (filename == NULL) {
1071                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1072                 talloc_free(tmp_ctx);
1073                 return -1;
1074         }
1075
1076         if (stat(filename, &st) != 0) {
1077                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename));
1078                 talloc_free(tmp_ctx);
1079                 return -1;
1080         }
1081
1082         if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) {
1083                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename));
1084                 talloc_free(tmp_ctx);
1085                 return -1;
1086         }
1087
1088         talloc_free(tmp_ctx);
1089         return 0;
1090 }