lower the debug levels for the "create FD messages" so we dont fill up the logs.
[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 (is_monitor == 1) {
597                         if (ctdb_ctrl_event_script_stop(ctdb, ret) != 0) {
598                                 DEBUG(DEBUG_ERR,(__location__ " Failed to stop event script monitoring\n"));
599                                 talloc_free(tmp_ctx);
600                                 return -1;
601                         }
602                 }
603
604                 /* return an error if the script failed */
605                 if (ret != 0) {
606                         DEBUG(DEBUG_ERR,("Event script %s failed with error %d\n", cmdstr, ret));
607                         if (is_monitor == 1) {
608                                 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
609                                         DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
610                                         talloc_free(tmp_ctx);
611                                         return -1;
612                                 }
613                         }
614
615                         talloc_free(tmp_ctx);
616                         return ret;
617                 }
618         }
619
620         child_state.start = timeval_current();
621         child_state.script_running = "finished";
622         
623         if (is_monitor == 1) {
624                 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
625                         DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
626                         talloc_free(tmp_ctx);
627                         return -1;
628                 }
629         }
630
631         talloc_free(tmp_ctx);
632         return 0;
633 }
634
635 /* called when child is finished */
636 static void ctdb_event_script_handler(struct event_context *ev, struct fd_event *fde, 
637                                       uint16_t flags, void *p)
638 {
639         struct ctdb_event_script_state *state = 
640                 talloc_get_type(p, struct ctdb_event_script_state);
641         void (*callback)(struct ctdb_context *, int, void *) = state->callback;
642         void *private_data = state->private_data;
643         struct ctdb_context *ctdb = state->ctdb;
644         signed char rt = -1;
645
646         read(state->fd[0], &rt, sizeof(rt));
647
648         DEBUG(DEBUG_INFO,(__location__ " Eventscript %s finished with state %d\n", state->options, rt));
649
650         talloc_set_destructor(state, NULL);
651         talloc_free(state);
652         callback(ctdb, rt, private_data);
653
654         ctdb->event_script_timeouts = 0;
655 }
656
657 static void ctdb_ban_self(struct ctdb_context *ctdb, uint32_t ban_period)
658 {
659         TDB_DATA data;
660         struct ctdb_ban_time bantime;
661
662         bantime.pnn  = ctdb->pnn;
663         bantime.time = ban_period;
664
665         data.dsize = sizeof(bantime);
666         data.dptr  = (uint8_t *)&bantime;
667
668         ctdb_control_set_ban_state(ctdb, data);
669 }
670
671
672 /* called when child times out */
673 static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, 
674                                       struct timeval t, void *p)
675 {
676         struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
677         void (*callback)(struct ctdb_context *, int, void *) = state->callback;
678         void *private_data = state->private_data;
679         struct ctdb_context *ctdb = state->ctdb;
680         char *options;
681         struct ctdb_monitoring_status *monitoring_status =
682                 talloc_get_type(ctdb->script_monitoring_ctx,
683                         struct ctdb_monitoring_status);
684
685         DEBUG(DEBUG_ERR,("Event script timed out : %s count : %u  pid : %d\n", state->options, ctdb->event_script_timeouts, state->child));
686         if (kill(state->child, 0) != 0) {
687                 DEBUG(DEBUG_ERR,("Event script child process already dead, errno %s(%d)\n", strerror(errno), errno));
688                 callback(ctdb, 0, private_data);
689
690                 talloc_set_destructor(state, NULL);
691                 talloc_free(state);
692                 return;
693         }
694
695         options = talloc_strdup(ctdb, state->options);
696         CTDB_NO_MEMORY_VOID(ctdb, options);
697
698         talloc_free(state);
699         if (!strcmp(options, "monitor")) {
700                 /* if it is a monitor event, we allow it to "hang" a few times
701                    before we declare it a failure and ban ourself (and make
702                    ourself unhealthy)
703                 */
704                 DEBUG(DEBUG_ERR, (__location__ " eventscript for monitor event timedout.\n"));
705
706                 ctdb->event_script_timeouts++;
707                 if (ctdb->event_script_timeouts > ctdb->tunable.script_ban_count) {
708                         if (ctdb->tunable.script_unhealthy_on_timeout != 0) {
709                                 DEBUG(DEBUG_ERR, ("Maximum timeout count %u reached for eventscript. Making node unhealthy\n", ctdb->tunable.script_ban_count));
710                                 callback(ctdb, -ETIME, private_data);
711                         } else {
712                                 ctdb->event_script_timeouts = 0;
713                                 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));
714                                 ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
715                                 callback(ctdb, -1, private_data);
716                         }
717                 } else {
718                         callback(ctdb, 0, private_data);
719                 }
720         } else if (!strcmp(options, "startup")) {
721                 DEBUG(DEBUG_ERR, (__location__ " eventscript for startup event timedout.\n"));
722                 callback(ctdb, -1, private_data);
723         } else {
724                 /* if it is not a monitor event we ban ourself immediately */
725                 DEBUG(DEBUG_ERR, (__location__ " eventscript for NON-monitor/NON-startup event timedout. Immediately banning ourself for %d seconds\n", ctdb->tunable.recovery_ban_period));
726                 ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
727                 callback(ctdb, -1, private_data);
728         }
729
730         if (monitoring_status != NULL) {
731                 struct ctdb_monitor_script_status *script;
732
733                 script = monitoring_status->scripts;
734                 if (script != NULL) {
735                         script->timedout = 1;
736                 }
737                 monitoring_status->status = MONITOR_SCRIPT_TIMEOUT;
738                 if (ctdb->last_monitoring_ctx) {
739                         talloc_free(ctdb->last_monitoring_ctx);
740                         ctdb->last_monitoring_ctx = ctdb->script_monitoring_ctx;
741                         ctdb->script_monitoring_ctx = NULL;
742                 }
743         }
744
745         talloc_free(options);
746 }
747
748 /*
749   destroy a running event script
750  */
751 static int event_script_destructor(struct ctdb_event_script_state *state)
752 {
753         DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
754
755         if (kill(state->child, SIGTERM) != 0) {
756                 DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
757         }
758
759         return 0;
760 }
761
762 /*
763   run the event script in the background, calling the callback when 
764   finished
765  */
766 static int ctdb_event_script_callback_v(struct ctdb_context *ctdb, 
767                                         struct timeval timeout,
768                                         TALLOC_CTX *mem_ctx,
769                                         void (*callback)(struct ctdb_context *, int, void *),
770                                         void *private_data,
771                                         const char *fmt, va_list ap)
772 {
773         struct ctdb_event_script_state *state;
774         int ret;
775
776         state = talloc(mem_ctx, struct ctdb_event_script_state);
777         CTDB_NO_MEMORY(ctdb, state);
778
779         state->ctdb = ctdb;
780         state->callback = callback;
781         state->private_data = private_data;
782         state->options = talloc_vasprintf(state, fmt, ap);
783         CTDB_NO_MEMORY(ctdb, state->options);
784
785         DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s\n", state->options));
786         
787         ret = pipe(state->fd);
788         if (ret != 0) {
789                 talloc_free(state);
790                 return -1;
791         }
792
793         state->child = fork();
794
795         if (state->child == (pid_t)-1) {
796                 close(state->fd[0]);
797                 close(state->fd[1]);
798                 talloc_free(state);
799                 return -1;
800         }
801
802         if (state->child == 0) {
803                 signed char rt;
804
805                 close(state->fd[0]);
806                 set_close_on_exec(state->fd[1]);
807
808                 rt = ctdb_event_script_v(ctdb, state->options);
809                 while ((ret = write(state->fd[1], &rt, sizeof(rt))) != sizeof(rt)) {
810                         sleep(1);
811                 }
812                 _exit(rt);
813         }
814
815         talloc_set_destructor(state, event_script_destructor);
816
817         close(state->fd[1]);
818         set_close_on_exec(state->fd[0]);
819
820         DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child eventscript process\n", state->fd[0]));
821
822         event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
823                      ctdb_event_script_handler, state);
824
825         if (!timeval_is_zero(&timeout)) {
826                 event_add_timed(ctdb->ev, state, timeout, ctdb_event_script_timeout, state);
827         } else {
828                 DEBUG(DEBUG_ERR, (__location__ " eventscript %s called with no timeout\n", state->options));
829         }
830
831         return 0;
832 }
833
834
835 /*
836   run the event script in the background, calling the callback when 
837   finished
838  */
839 int ctdb_event_script_callback(struct ctdb_context *ctdb, 
840                                struct timeval timeout,
841                                TALLOC_CTX *mem_ctx,
842                                void (*callback)(struct ctdb_context *, int, void *),
843                                void *private_data,
844                                const char *fmt, ...)
845 {
846         va_list ap;
847         int ret;
848
849         va_start(ap, fmt);
850         ret = ctdb_event_script_callback_v(ctdb, timeout, mem_ctx, callback, private_data, fmt, ap);
851         va_end(ap);
852
853         return ret;
854 }
855
856
857 struct callback_status {
858         bool done;
859         int status;
860 };
861
862 /*
863   called when ctdb_event_script() finishes
864  */
865 static void event_script_callback(struct ctdb_context *ctdb, int status, void *private_data)
866 {
867         struct callback_status *s = (struct callback_status *)private_data;
868         s->done = true;
869         s->status = status;
870 }
871
872 /*
873   run the event script, waiting for it to complete. Used when the caller doesn't want to 
874   continue till the event script has finished.
875  */
876 int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
877 {
878         va_list ap;
879         int ret;
880         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
881         struct callback_status status;
882
883         va_start(ap, fmt);
884         ret = ctdb_event_script_callback_v(ctdb, 
885                         timeval_current_ofs(ctdb->tunable.script_timeout, 0),
886                         tmp_ctx, event_script_callback, &status, fmt, ap);
887         va_end(ap);
888
889         if (ret != 0) {
890                 talloc_free(tmp_ctx);
891                 return ret;
892         }
893
894         status.status = -1;
895         status.done = false;
896
897         while (status.done == false && event_loop_once(ctdb->ev) == 0) /* noop */;
898
899         talloc_free(tmp_ctx);
900
901         return status.status;
902 }
903
904
905 struct eventscript_callback_state {
906         struct ctdb_req_control *c;
907 };
908
909 /*
910   called when takeip event finishes
911  */
912 static void run_eventscripts_callback(struct ctdb_context *ctdb, int status, 
913                                  void *private_data)
914 {
915         struct eventscript_callback_state *state = 
916                 talloc_get_type(private_data, struct eventscript_callback_state);
917
918         ctdb_enable_monitoring(ctdb);
919
920         if (status != 0) {
921                 DEBUG(DEBUG_ERR,(__location__ " Failed to forcibly run eventscripts\n"));
922                 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
923                 talloc_free(state);
924                 return;
925         }
926
927         /* the control succeeded */
928         ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
929         talloc_free(state);
930         return;
931 }
932
933 /*
934   A control to force running of the eventscripts from the ctdb client tool
935 */
936 int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
937                 struct ctdb_req_control *c,
938                 TDB_DATA indata, bool *async_reply)
939 {
940         int ret;
941         struct eventscript_callback_state *state;
942
943         /* kill off any previous invokations of forced eventscripts */
944         if (ctdb->eventscripts_ctx) {
945                 talloc_free(ctdb->eventscripts_ctx);
946         }
947         ctdb->eventscripts_ctx = talloc_new(ctdb);
948         CTDB_NO_MEMORY(ctdb, ctdb->eventscripts_ctx);
949
950         state = talloc(ctdb->eventscripts_ctx, struct eventscript_callback_state);
951         CTDB_NO_MEMORY(ctdb, state);
952
953         state->c = talloc_steal(state, c);
954
955         DEBUG(DEBUG_NOTICE,("Forced running of eventscripts with arguments %s\n", indata.dptr));
956
957         if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
958                 DEBUG(DEBUG_ERR, (__location__ " Aborted running eventscript \"%s\" while in RECOVERY mode\n", indata.dptr));
959                 return -1;
960         }
961
962         ctdb_disable_monitoring(ctdb);
963
964         ret = ctdb_event_script_callback(ctdb, 
965                          timeval_current_ofs(ctdb->tunable.script_timeout, 0),
966                          state, run_eventscripts_callback, state,
967                          (const char *)indata.dptr);
968
969         if (ret != 0) {
970                 ctdb_enable_monitoring(ctdb);
971                 DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
972                 talloc_free(state);
973                 return -1;
974         }
975
976         /* tell ctdb_control.c that we will be replying asynchronously */
977         *async_reply = true;
978
979         return 0;
980 }
981
982
983
984 int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata)
985 {
986         const char *script;
987         struct stat st;
988         char *filename;
989         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
990
991         script = (char *)indata.dptr;
992         if (indata.dsize == 0) {
993                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
994                 talloc_free(tmp_ctx);
995                 return -1;
996         }
997         if (indata.dptr[indata.dsize - 1] != '\0') {
998                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
999                 talloc_free(tmp_ctx);
1000                 return -1;
1001         }
1002         if (index(script,'/') != NULL) {
1003                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script));
1004                 talloc_free(tmp_ctx);
1005                 return -1;
1006         }
1007
1008
1009         if (stat(ctdb->event_script_dir, &st) != 0 && 
1010             errno == ENOENT) {
1011                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1012                 talloc_free(tmp_ctx);
1013                 return -1;
1014         }
1015
1016
1017         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1018         if (filename == NULL) {
1019                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1020                 talloc_free(tmp_ctx);
1021                 return -1;
1022         }
1023
1024         if (stat(filename, &st) != 0) {
1025                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename));
1026                 talloc_free(tmp_ctx);
1027                 return -1;
1028         }
1029
1030         if (chmod(filename, st.st_mode | S_IXUSR) == -1) {
1031                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename));
1032                 talloc_free(tmp_ctx);
1033                 return -1;
1034         }
1035
1036         talloc_free(tmp_ctx);
1037         return 0;
1038 }
1039
1040 int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1041 {
1042         const char *script;
1043         struct stat st;
1044         char *filename;
1045         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1046
1047         script = (char *)indata.dptr;
1048         if (indata.dsize == 0) {
1049                 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1050                 talloc_free(tmp_ctx);
1051                 return -1;
1052         }
1053         if (indata.dptr[indata.dsize - 1] != '\0') {
1054                 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1055                 talloc_free(tmp_ctx);
1056                 return -1;
1057         }
1058         if (index(script,'/') != NULL) {
1059                 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script));
1060                 talloc_free(tmp_ctx);
1061                 return -1;
1062         }
1063
1064
1065         if (stat(ctdb->event_script_dir, &st) != 0 && 
1066             errno == ENOENT) {
1067                 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1068                 talloc_free(tmp_ctx);
1069                 return -1;
1070         }
1071
1072
1073         filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1074         if (filename == NULL) {
1075                 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1076                 talloc_free(tmp_ctx);
1077                 return -1;
1078         }
1079
1080         if (stat(filename, &st) != 0) {
1081                 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename));
1082                 talloc_free(tmp_ctx);
1083                 return -1;
1084         }
1085
1086         if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) {
1087                 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename));
1088                 talloc_free(tmp_ctx);
1089                 return -1;
1090         }
1091
1092         talloc_free(tmp_ctx);
1093         return 0;
1094 }