4 Copyright (C) Andrew Tridgell 2007
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.
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.
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/>.
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"
32 const char *script_running;
35 static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p);
38 ctdbd sends us a SIGTERM when we should time out the current script
40 static void sigterm(int sig)
42 char tbuf[100], buf[200];
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()));
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());
54 DEBUG(DEBUG_ERR,("Logged timedout eventscript : %s\n", buf));
56 /* all the child processes will be running in the same process group */
57 kill(-getpgrp(), SIGKILL);
61 struct ctdb_event_script_state {
62 struct ctdb_context *ctdb;
64 void (*callback)(struct ctdb_context *, int, void *);
68 struct timed_event *te;
69 struct timeval timeout;
73 struct ctdb_monitor_script_status {
74 struct ctdb_monitor_script_status *next;
77 struct timeval finished;
84 struct ctdb_monitor_status {
86 struct timeval finished;
88 struct ctdb_monitor_script_status *scripts;
89 struct ctdb_event_script_state *state;
93 /* called from ctdb_logging when we have received output on STDERR from
94 * one of the eventscripts
96 int ctdb_log_event_script_output(struct ctdb_context *ctdb, char *str, uint16_t len)
98 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
99 struct ctdb_monitor_script_status *script;
101 if (monitoring_status == NULL) {
105 script = monitoring_status->scripts;
106 if (script == NULL) {
110 if (script->output == NULL) {
111 script->output = talloc_asprintf(script, "%*.*s", len, len, str);
113 script->output = talloc_asprintf_append(script->output, "%*.*s", len, len, str);
119 /* called from the event script child process when we are starting a new
122 int32_t ctdb_control_event_script_init(struct ctdb_context *ctdb)
124 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
126 DEBUG(DEBUG_INFO, ("event script init called\n"));
128 if (monitoring_status == NULL) {
129 DEBUG(DEBUG_ERR,(__location__ " Init called when context is NULL\n"));
133 monitoring_status->start = timeval_current();
139 /* called from the event script child process when we are star running
142 int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA indata)
144 const char *name = (const char *)indata.dptr;
145 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
146 struct ctdb_event_script_state *state;
147 struct ctdb_monitor_script_status *script;
149 DEBUG(DEBUG_INFO, ("event script start called : %s\n", name));
151 if (monitoring_status == NULL) {
152 DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when starting to run script %s\n", name));
156 script = talloc_zero(monitoring_status, struct ctdb_monitor_script_status);
157 if (script == NULL) {
158 DEBUG(DEBUG_ERR,(__location__ " Failed to talloc ctdb_monitor_script_status for script %s\n", name));
162 script->next = monitoring_status->scripts;
163 script->name = talloc_strdup(script, name);
164 CTDB_NO_MEMORY(ctdb, script->name);
165 script->start = timeval_current();
166 monitoring_status->scripts = script;
168 state = monitoring_status->state;
170 /* reset the timeout for the next eventscript */
171 if (!timeval_is_zero(&state->timeout)) {
172 if (state->te != NULL) {
173 talloc_free(state->te);
176 state->te = event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
184 /* called from the event script child process when we have finished running
187 int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indata)
189 int32_t res = *((int32_t *)indata.dptr);
190 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
191 struct ctdb_monitor_script_status *script;
193 if (monitoring_status == NULL) {
194 DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when script finished.\n"));
198 script = monitoring_status->scripts;
199 if (script == NULL) {
200 DEBUG(DEBUG_ERR,(__location__ " script is NULL when the script had finished\n"));
204 script->finished = timeval_current();
205 script->status = res;
207 DEBUG(DEBUG_INFO, ("event script stop called for script:%s duration:%.1f status:%d\n", script->name, timeval_elapsed(&script->start), (int)res));
212 /* called from the event script child process when we have a disabled script
214 int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA indata)
216 const char *name = (const char *)indata.dptr;
217 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
218 struct ctdb_monitor_script_status *script;
220 DEBUG(DEBUG_INFO, ("event script disabed called for script %s\n", name));
222 if (monitoring_status == NULL) {
223 DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when script finished.\n"));
227 script = monitoring_status->scripts;
228 if (script == NULL) {
229 DEBUG(DEBUG_ERR,(__location__ " script is NULL when the script had finished\n"));
233 script->finished = timeval_current();
235 script->disabled = 1;
240 /* called from the event script child process when we have completed a
243 int32_t ctdb_control_event_script_finished(struct ctdb_context *ctdb)
245 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
247 DEBUG(DEBUG_INFO, ("event script finished called\n"));
249 if (monitoring_status == NULL) {
250 DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when monitoring event finished\n"));
254 monitoring_status->finished = timeval_current();
255 monitoring_status->status = MONITOR_SCRIPT_OK;
257 if (ctdb->last_monitor_ctx) {
258 talloc_free(ctdb->last_monitor_ctx);
259 ctdb->last_monitor_ctx = NULL;
261 ctdb->last_monitor_ctx = talloc_steal(ctdb, ctdb->script_monitor_ctx);
262 ctdb->script_monitor_ctx = NULL;
267 static struct ctdb_monitoring_wire *marshall_monitoring_scripts(TALLOC_CTX *mem_ctx, struct ctdb_monitoring_wire *monitoring_scripts, struct ctdb_monitor_script_status *script)
269 struct ctdb_monitoring_script_wire script_wire;
272 if (script == NULL) {
273 return monitoring_scripts;
275 monitoring_scripts = marshall_monitoring_scripts(mem_ctx, monitoring_scripts, script->next);
276 if (monitoring_scripts == NULL) {
280 bzero(&script_wire, sizeof(struct ctdb_monitoring_script_wire));
281 strncpy(script_wire.name, script->name, MAX_SCRIPT_NAME);
282 script_wire.start = script->start;
283 script_wire.finished = script->finished;
284 script_wire.disabled = script->disabled;
285 script_wire.status = script->status;
286 script_wire.timedout = script->timedout;
287 if (script->output != NULL) {
288 strncpy(script_wire.output, script->output, MAX_SCRIPT_OUTPUT);
291 size = talloc_get_size(monitoring_scripts);
292 monitoring_scripts = talloc_realloc_size(mem_ctx, monitoring_scripts, size + sizeof(struct ctdb_monitoring_script_wire));
293 if (monitoring_scripts == NULL) {
294 DEBUG(DEBUG_ERR,(__location__ " Failed to talloc_resize monitoring_scripts blob\n"));
298 memcpy(&monitoring_scripts->scripts[monitoring_scripts->num_scripts], &script_wire, sizeof(script_wire));
299 monitoring_scripts->num_scripts++;
301 return monitoring_scripts;
304 int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb, TDB_DATA *outdata)
306 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->last_monitor_ctx;
307 struct ctdb_monitoring_wire *monitoring_scripts;
309 if (monitoring_status == NULL) {
310 DEBUG(DEBUG_ERR,(__location__ " last_monitor_ctx is NULL when reading status\n"));
314 monitoring_scripts = talloc_size(outdata, offsetof(struct ctdb_monitoring_wire, scripts));
315 if (monitoring_scripts == NULL) {
316 DEBUG(DEBUG_ERR,(__location__ " failed to talloc monitoring_scripts structure\n"));
320 monitoring_scripts->num_scripts = 0;
321 monitoring_scripts = marshall_monitoring_scripts(outdata, monitoring_scripts, monitoring_status->scripts);
322 if (monitoring_scripts == NULL) {
323 DEBUG(DEBUG_ERR,(__location__ " Monitoring scritps is NULL. can not return data to client\n"));
327 outdata->dsize = talloc_get_size(monitoring_scripts);
328 outdata->dptr = (uint8_t *)monitoring_scripts;
333 struct ctdb_script_tree_item {
338 struct ctdb_script_list {
339 struct ctdb_script_list *next;
344 static struct ctdb_script_list *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx)
350 struct ctdb_script_list *head, *tail, *new_item;
351 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
352 struct ctdb_script_tree_item *tree_item;
356 the service specific event scripts
358 if (stat(ctdb->event_script_dir, &st) != 0 &&
360 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
361 talloc_free(tmp_ctx);
365 /* create a tree to store all the script names in */
366 tree = trbt_create(tmp_ctx, 0);
368 /* scan all directory entries and insert all valid scripts into the
371 dir = opendir(ctdb->event_script_dir);
373 DEBUG(DEBUG_CRIT,("Failed to open event script directory '%s'\n", ctdb->event_script_dir));
374 talloc_free(tmp_ctx);
379 while ((de=readdir(dir)) != NULL) {
384 namlen = strlen(de->d_name);
390 if (de->d_name[namlen-1] == '~') {
391 /* skip files emacs left behind */
395 if (de->d_name[2] != '.') {
399 if (sscanf(de->d_name, "%02u.", &num) != 1) {
403 /* Make sure the event script is executable */
404 str = talloc_asprintf(tree, "%s/%s", ctdb->event_script_dir, de->d_name);
405 if (stat(str, &st) != 0) {
406 DEBUG(DEBUG_ERR,("Could not stat event script %s. Ignoring this event script\n", str));
411 tree_item = talloc(tree, struct ctdb_script_tree_item);
412 if (tree_item == NULL) {
413 DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new tree item\n"));
414 talloc_free(tmp_ctx);
418 tree_item->is_enabled = 1;
419 if (!(st.st_mode & S_IXUSR)) {
420 DEBUG(DEBUG_INFO,("Event script %s is not executable. Ignoring this event script\n", str));
421 tree_item->is_enabled = 0;
424 tree_item->name = talloc_strdup(tree_item, de->d_name);
425 if (tree_item->name == NULL) {
426 DEBUG(DEBUG_ERR,(__location__ " Failed to allocate script name.\n"));
427 talloc_free(tmp_ctx);
431 /* store the event script in the tree */
432 trbt_insert32(tree, (num<<16)|count++, tree_item);
440 /* fetch the scripts from the tree one by one and add them to the linked
443 while ((tree_item=trbt_findfirstarray32(tree, 1)) != NULL) {
445 new_item = talloc(tmp_ctx, struct ctdb_script_list);
446 if (new_item == NULL) {
447 DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new list item\n"));
448 talloc_free(tmp_ctx);
452 new_item->next = NULL;
453 new_item->name = talloc_steal(new_item, tree_item->name);
454 new_item->is_enabled = tree_item->is_enabled;
460 tail->next = new_item;
464 talloc_steal(mem_ctx, new_item);
466 /* remove this script from the tree */
467 talloc_free(tree_item);
470 talloc_free(tmp_ctx);
477 run the event script - varargs version
478 this function is called and run in the context of a forked child
479 which allows it to do blocking calls such as system()
481 static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options)
485 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
486 struct ctdb_script_list *scripts, *current;
489 if (!strcmp(options, "monitor")) {
493 if (is_monitor == 1) {
494 /* This is running in the forked child process. At this stage
495 * we want to switch from being a ctdb daemon into being a
496 * client and connect to the real local daemon.
498 if (switch_from_server_to_client(ctdb) != 0) {
499 DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch eventscript child into client mode. shutting down.\n"));
503 if (ctdb_ctrl_event_script_init(ctdb) != 0) {
504 DEBUG(DEBUG_ERR,(__location__ " Failed to init event script monitoring\n"));
505 talloc_free(tmp_ctx);
510 if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
511 /* we guarantee that only some specifically allowed event scripts are run
513 const char *allowed_scripts[] = {"startrecovery", "shutdown", "releaseip", "stopped" };
515 for (i=0;i<ARRAY_SIZE(allowed_scripts);i++) {
516 if (strncmp(options, allowed_scripts[i], strlen(allowed_scripts[i])) == 0) break;
518 if (i == ARRAY_SIZE(allowed_scripts)) {
519 DEBUG(DEBUG_ERR,("Refusing to run event scripts with option '%s' while in recovery\n",
521 talloc_free(tmp_ctx);
526 if (setpgid(0,0) != 0) {
527 DEBUG(DEBUG_ERR,("Failed to create process group for event scripts - %s\n",
529 talloc_free(tmp_ctx);
533 signal(SIGTERM, sigterm);
535 child_state.start = timeval_current();
536 child_state.script_running = "startup";
538 scripts = ctdb_get_script_list(ctdb, tmp_ctx);
540 /* fetch the scripts from the tree one by one and execute
543 for (current=scripts; current; current=current->next) {
544 /* we dont run disabled scripts, we just report they are disabled */
545 cmdstr = talloc_asprintf(tmp_ctx, "%s/%s %s",
546 ctdb->event_script_dir,
547 current->name, options);
548 CTDB_NO_MEMORY(ctdb, cmdstr);
550 DEBUG(DEBUG_INFO,("Executing event script %s\n",cmdstr));
552 child_state.start = timeval_current();
553 child_state.script_running = cmdstr;
555 if (is_monitor == 1) {
556 if (ctdb_ctrl_event_script_start(ctdb, current->name) != 0) {
557 DEBUG(DEBUG_ERR,(__location__ " Failed to start event script monitoring\n"));
558 talloc_free(tmp_ctx);
562 if (!current->is_enabled) {
563 if (ctdb_ctrl_event_script_disabled(ctdb, current->name) != 0) {
564 DEBUG(DEBUG_ERR,(__location__ " Failed to report disabled eventscript\n"));
565 talloc_free(tmp_ctx);
572 if (!current->is_enabled) {
576 ret = system(cmdstr);
577 /* if the system() call was successful, translate ret into the
578 return code from the command
581 ret = WEXITSTATUS(ret);
585 DEBUG(DEBUG_ERR,("Script %s returned status 127. Someone just deleted it?\n", cmdstr));
588 if (is_monitor == 1) {
589 if (ctdb_ctrl_event_script_stop(ctdb, ret) != 0) {
590 DEBUG(DEBUG_ERR,(__location__ " Failed to stop event script monitoring\n"));
591 talloc_free(tmp_ctx);
596 /* return an error if the script failed */
598 DEBUG(DEBUG_ERR,("Event script %s failed with error %d\n", cmdstr, ret));
599 if (is_monitor == 1) {
600 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
601 DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
602 talloc_free(tmp_ctx);
607 talloc_free(tmp_ctx);
612 child_state.start = timeval_current();
613 child_state.script_running = "finished";
615 if (is_monitor == 1) {
616 if (ctdb_ctrl_event_script_finished(ctdb) != 0) {
617 DEBUG(DEBUG_ERR,(__location__ " Failed to finish event script monitoring\n"));
618 talloc_free(tmp_ctx);
623 talloc_free(tmp_ctx);
627 /* called when child is finished */
628 static void ctdb_event_script_handler(struct event_context *ev, struct fd_event *fde,
629 uint16_t flags, void *p)
631 struct ctdb_event_script_state *state =
632 talloc_get_type(p, struct ctdb_event_script_state);
633 struct ctdb_context *ctdb = state->ctdb;
636 read(state->fd[0], &rt, sizeof(rt));
638 DEBUG(DEBUG_INFO,(__location__ " Eventscript %s finished with state %d\n", state->options, rt));
640 if (state->callback) {
641 state->callback(ctdb, rt, state->private_data);
642 state->callback = NULL;
645 talloc_set_destructor(state, NULL);
647 ctdb->event_script_timeouts = 0;
650 static void ctdb_ban_self(struct ctdb_context *ctdb, uint32_t ban_period)
653 struct ctdb_ban_time bantime;
655 bantime.pnn = ctdb->pnn;
656 bantime.time = ban_period;
658 data.dsize = sizeof(bantime);
659 data.dptr = (uint8_t *)&bantime;
661 ctdb_control_set_ban_state(ctdb, data);
665 /* called when child times out */
666 static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te,
667 struct timeval t, void *p)
669 struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
670 void *private_data = state->private_data;
671 struct ctdb_context *ctdb = state->ctdb;
673 struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
677 DEBUG(DEBUG_ERR,("Event script timed out : %s count : %u pid : %d\n", state->options, ctdb->event_script_timeouts, state->child));
678 if (kill(state->child, 0) != 0) {
679 DEBUG(DEBUG_ERR,("Event script child process already dead, errno %s(%d)\n", strerror(errno), errno));
680 if (state->callback) {
681 state->callback(ctdb, 0, private_data);
682 state->callback = NULL;
684 talloc_set_destructor(state, NULL);
689 options = talloc_strdup(ctdb, state->options);
690 CTDB_NO_MEMORY_VOID(ctdb, options);
693 if (!strcmp(options, "monitor")) {
694 /* if it is a monitor event, we allow it to "hang" a few times
695 before we declare it a failure and ban ourself (and make
698 DEBUG(DEBUG_ERR, (__location__ " eventscript for monitor event timedout.\n"));
700 ctdb->event_script_timeouts++;
701 if (ctdb->event_script_timeouts > ctdb->tunable.script_ban_count) {
702 if (ctdb->tunable.script_unhealthy_on_timeout != 0) {
703 DEBUG(DEBUG_ERR, ("Maximum timeout count %u reached for eventscript. Making node unhealthy\n", ctdb->tunable.script_ban_count));
704 if (state->callback) {
705 state->callback(ctdb, -ETIME, private_data);
706 state->callback = NULL;
709 ctdb->event_script_timeouts = 0;
710 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));
711 ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
712 if (state->callback) {
713 state->callback(ctdb, -1, private_data);
714 state->callback = NULL;
718 if (state->callback) {
719 state->callback(ctdb, 0, private_data);
720 state->callback = NULL;
723 } else if (!strcmp(options, "startup")) {
724 DEBUG(DEBUG_ERR, (__location__ " eventscript for startup event timedout.\n"));
725 if (state->callback) {
726 state->callback(ctdb, -1, private_data);
727 state->callback = NULL;
730 /* if it is not a monitor event we ban ourself immediately */
731 DEBUG(DEBUG_ERR, (__location__ " eventscript for NON-monitor/NON-startup event timedout. Immediately banning ourself for %d seconds\n", ctdb->tunable.recovery_ban_period));
732 ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
733 if (state->callback) {
734 state->callback(ctdb, -1, private_data);
735 state->callback = NULL;
739 if ((!strcmp(options, "monitor")) && (monitoring_status != NULL)) {
740 struct ctdb_monitor_script_status *script;
742 script = monitoring_status->scripts;
743 if (script != NULL) {
744 script->timedout = 1;
746 monitoring_status->status = MONITOR_SCRIPT_TIMEOUT;
747 if (ctdb->last_monitor_ctx) {
748 talloc_free(ctdb->last_monitor_ctx);
749 ctdb->last_monitor_ctx = NULL;
751 ctdb->last_monitor_ctx = talloc_steal(ctdb, ctdb->script_monitor_ctx);
752 ctdb->script_monitor_ctx = NULL;
755 talloc_free(options);
759 destroy a running event script
761 static int event_script_destructor(struct ctdb_event_script_state *state)
763 DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
765 if (state->callback) {
766 state->callback(state->ctdb, 0, state->private_data);
767 state->callback = NULL;
770 if (kill(state->child, SIGTERM) != 0) {
771 DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
778 run the event script in the background, calling the callback when
781 static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
782 struct timeval timeout,
783 void (*callback)(struct ctdb_context *, int, void *),
785 const char *fmt, va_list ap)
787 struct ctdb_monitor_status *monitoring_status;
788 struct ctdb_event_script_state *state;
791 if (!strcmp(fmt, "monitor")) {
792 if (ctdb->script_monitor_ctx != NULL) {
793 talloc_free(ctdb->script_monitor_ctx);
794 ctdb->script_monitor_ctx = NULL;
796 monitoring_status = talloc_zero(ctdb, struct ctdb_monitor_status);
798 if (ctdb->event_script_ctx == NULL) {
799 ctdb->event_script_ctx = talloc_zero(ctdb, struct ctdb_monitor_status);
801 monitoring_status = ctdb->event_script_ctx;
804 if (monitoring_status == NULL) {
805 DEBUG(DEBUG_ERR, (__location__ " ERROR: Failed to talloc script_monitoring context\n"));
809 state = talloc(monitoring_status, struct ctdb_event_script_state);
811 DEBUG(DEBUG_ERR,(__location__ " could not allocate state\n"));
814 monitoring_status->state = state;
817 state->callback = callback;
818 state->private_data = private_data;
819 state->options = talloc_vasprintf(state, fmt, ap);
820 state->timeout = timeout;
822 if (state->options == NULL) {
823 DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
828 DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s\n", state->options));
830 ret = pipe(state->fd);
836 state->child = fork();
838 if (state->child == (pid_t)-1) {
845 if (state->child == 0) {
849 set_close_on_exec(state->fd[1]);
851 rt = ctdb_event_script_v(ctdb, state->options);
852 while ((ret = write(state->fd[1], &rt, sizeof(rt))) != sizeof(rt)) {
853 write(state->fd[1], &rt, sizeof(rt));
859 talloc_set_destructor(state, event_script_destructor);
860 if (!strcmp(fmt, "monitor")) {
861 ctdb->script_monitor_ctx = monitoring_status;
863 ctdb->event_script_ctx = monitoring_status;
867 set_close_on_exec(state->fd[0]);
869 DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child eventscript process\n", state->fd[0]));
871 event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
872 ctdb_event_script_handler, state);
874 if (!timeval_is_zero(&state->timeout)) {
875 state->te = event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
877 DEBUG(DEBUG_ERR, (__location__ " eventscript %s called with no timeout\n", state->options));
885 run the event script in the background, calling the callback when
888 int ctdb_event_script_callback(struct ctdb_context *ctdb,
889 struct timeval timeout,
891 void (*callback)(struct ctdb_context *, int, void *),
893 const char *fmt, ...)
899 ret = ctdb_event_script_callback_v(ctdb, timeout, callback, private_data, fmt, ap);
906 struct callback_status {
912 called when ctdb_event_script() finishes
914 static void event_script_callback(struct ctdb_context *ctdb, int status, void *private_data)
916 struct callback_status *s = (struct callback_status *)private_data;
922 run the event script, waiting for it to complete. Used when the caller doesn't want to
923 continue till the event script has finished.
925 int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
929 struct callback_status status;
932 ret = ctdb_event_script_callback_v(ctdb,
933 timeval_set(ctdb->tunable.script_timeout, 0),
934 event_script_callback, &status, fmt, ap);
944 while (status.done == false && event_loop_once(ctdb->ev) == 0) /* noop */;
946 return status.status;
950 struct eventscript_callback_state {
951 struct ctdb_req_control *c;
955 called when takeip event finishes
957 static void run_eventscripts_callback(struct ctdb_context *ctdb, int status,
960 struct eventscript_callback_state *state =
961 talloc_get_type(private_data, struct eventscript_callback_state);
963 ctdb_enable_monitoring(ctdb);
966 DEBUG(DEBUG_ERR,(__location__ " Failed to forcibly run eventscripts\n"));
967 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
972 /* the control succeeded */
973 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
979 A control to force running of the eventscripts from the ctdb client tool
981 int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
982 struct ctdb_req_control *c,
983 TDB_DATA indata, bool *async_reply)
986 struct eventscript_callback_state *state;
988 /* kill off any previous invokations of forced eventscripts */
989 if (ctdb->eventscripts_ctx) {
990 talloc_free(ctdb->eventscripts_ctx);
992 ctdb->eventscripts_ctx = talloc_new(ctdb);
993 CTDB_NO_MEMORY(ctdb, ctdb->eventscripts_ctx);
995 state = talloc(ctdb->eventscripts_ctx, struct eventscript_callback_state);
996 CTDB_NO_MEMORY(ctdb, state);
998 state->c = talloc_steal(state, c);
1000 DEBUG(DEBUG_NOTICE,("Forced running of eventscripts with arguments %s\n", indata.dptr));
1002 if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
1003 DEBUG(DEBUG_ERR, (__location__ " Aborted running eventscript \"%s\" while in RECOVERY mode\n", indata.dptr));
1007 ctdb_disable_monitoring(ctdb);
1009 ret = ctdb_event_script_callback(ctdb,
1010 timeval_set(ctdb->tunable.script_timeout, 0),
1011 state, run_eventscripts_callback, state,
1012 "%s", (const char *)indata.dptr);
1015 ctdb_enable_monitoring(ctdb);
1016 DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
1021 /* tell ctdb_control.c that we will be replying asynchronously */
1022 *async_reply = true;
1029 int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1034 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1036 script = (char *)indata.dptr;
1037 if (indata.dsize == 0) {
1038 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1039 talloc_free(tmp_ctx);
1042 if (indata.dptr[indata.dsize - 1] != '\0') {
1043 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1044 talloc_free(tmp_ctx);
1047 if (index(script,'/') != NULL) {
1048 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script));
1049 talloc_free(tmp_ctx);
1054 if (stat(ctdb->event_script_dir, &st) != 0 &&
1056 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1057 talloc_free(tmp_ctx);
1062 filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1063 if (filename == NULL) {
1064 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1065 talloc_free(tmp_ctx);
1069 if (stat(filename, &st) != 0) {
1070 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename));
1071 talloc_free(tmp_ctx);
1075 if (chmod(filename, st.st_mode | S_IXUSR) == -1) {
1076 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename));
1077 talloc_free(tmp_ctx);
1081 talloc_free(tmp_ctx);
1085 int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1090 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1092 script = (char *)indata.dptr;
1093 if (indata.dsize == 0) {
1094 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1095 talloc_free(tmp_ctx);
1098 if (indata.dptr[indata.dsize - 1] != '\0') {
1099 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1100 talloc_free(tmp_ctx);
1103 if (index(script,'/') != NULL) {
1104 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script));
1105 talloc_free(tmp_ctx);
1110 if (stat(ctdb->event_script_dir, &st) != 0 &&
1112 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1113 talloc_free(tmp_ctx);
1118 filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1119 if (filename == NULL) {
1120 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1121 talloc_free(tmp_ctx);
1125 if (stat(filename, &st) != 0) {
1126 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename));
1127 talloc_free(tmp_ctx);
1131 if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) {
1132 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename));
1133 talloc_free(tmp_ctx);
1137 talloc_free(tmp_ctx);