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