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