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 (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 (ctdb->script_monitor_ctx != NULL) {
792 talloc_free(ctdb->script_monitor_ctx);
793 ctdb->script_monitor_ctx = NULL;
795 monitoring_status = talloc_zero(ctdb, struct ctdb_monitor_status);
796 if (monitoring_status == NULL) {
797 DEBUG(DEBUG_ERR, (__location__ " ERROR: Failed to talloc script_monitoring context\n"));
801 state = talloc(monitoring_status, struct ctdb_event_script_state);
803 DEBUG(DEBUG_ERR,(__location__ " could not allocate state\n"));
804 talloc_free(monitoring_status);
807 monitoring_status->state = state;
810 state->callback = callback;
811 state->private_data = private_data;
812 state->options = talloc_vasprintf(state, fmt, ap);
813 state->timeout = timeout;
815 if (state->options == NULL) {
816 DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
817 talloc_free(monitoring_status);
821 DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s\n", state->options));
823 ret = pipe(state->fd);
825 talloc_free(monitoring_status);
829 state->child = fork();
831 if (state->child == (pid_t)-1) {
834 talloc_free(monitoring_status);
838 if (state->child == 0) {
842 set_close_on_exec(state->fd[1]);
844 rt = ctdb_event_script_v(ctdb, state->options);
845 while ((ret = write(state->fd[1], &rt, sizeof(rt))) != sizeof(rt)) {
846 write(state->fd[1], &rt, sizeof(rt));
852 talloc_set_destructor(state, event_script_destructor);
853 ctdb->script_monitor_ctx = monitoring_status;
856 set_close_on_exec(state->fd[0]);
858 DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child eventscript process\n", state->fd[0]));
860 event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
861 ctdb_event_script_handler, state);
863 if (!timeval_is_zero(&state->timeout)) {
864 state->te = event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
866 DEBUG(DEBUG_ERR, (__location__ " eventscript %s called with no timeout\n", state->options));
874 run the event script in the background, calling the callback when
877 int ctdb_event_script_callback(struct ctdb_context *ctdb,
878 struct timeval timeout,
880 void (*callback)(struct ctdb_context *, int, void *),
882 const char *fmt, ...)
888 ret = ctdb_event_script_callback_v(ctdb, timeout, callback, private_data, fmt, ap);
895 struct callback_status {
901 called when ctdb_event_script() finishes
903 static void event_script_callback(struct ctdb_context *ctdb, int status, void *private_data)
905 struct callback_status *s = (struct callback_status *)private_data;
911 run the event script, waiting for it to complete. Used when the caller doesn't want to
912 continue till the event script has finished.
914 int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
918 struct callback_status status;
921 ret = ctdb_event_script_callback_v(ctdb,
922 timeval_set(ctdb->tunable.script_timeout, 0),
923 event_script_callback, &status, fmt, ap);
933 while (status.done == false && event_loop_once(ctdb->ev) == 0) /* noop */;
935 return status.status;
939 struct eventscript_callback_state {
940 struct ctdb_req_control *c;
944 called when takeip event finishes
946 static void run_eventscripts_callback(struct ctdb_context *ctdb, int status,
949 struct eventscript_callback_state *state =
950 talloc_get_type(private_data, struct eventscript_callback_state);
952 ctdb_enable_monitoring(ctdb);
955 DEBUG(DEBUG_ERR,(__location__ " Failed to forcibly run eventscripts\n"));
956 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
961 /* the control succeeded */
962 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
968 A control to force running of the eventscripts from the ctdb client tool
970 int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
971 struct ctdb_req_control *c,
972 TDB_DATA indata, bool *async_reply)
975 struct eventscript_callback_state *state;
977 /* kill off any previous invokations of forced eventscripts */
978 if (ctdb->eventscripts_ctx) {
979 talloc_free(ctdb->eventscripts_ctx);
981 ctdb->eventscripts_ctx = talloc_new(ctdb);
982 CTDB_NO_MEMORY(ctdb, ctdb->eventscripts_ctx);
984 state = talloc(ctdb->eventscripts_ctx, struct eventscript_callback_state);
985 CTDB_NO_MEMORY(ctdb, state);
987 state->c = talloc_steal(state, c);
989 DEBUG(DEBUG_NOTICE,("Forced running of eventscripts with arguments %s\n", indata.dptr));
991 if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
992 DEBUG(DEBUG_ERR, (__location__ " Aborted running eventscript \"%s\" while in RECOVERY mode\n", indata.dptr));
996 ctdb_disable_monitoring(ctdb);
998 ret = ctdb_event_script_callback(ctdb,
999 timeval_set(ctdb->tunable.script_timeout, 0),
1000 state, run_eventscripts_callback, state,
1001 "%s", (const char *)indata.dptr);
1004 ctdb_enable_monitoring(ctdb);
1005 DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
1010 /* tell ctdb_control.c that we will be replying asynchronously */
1011 *async_reply = true;
1018 int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1023 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1025 script = (char *)indata.dptr;
1026 if (indata.dsize == 0) {
1027 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1028 talloc_free(tmp_ctx);
1031 if (indata.dptr[indata.dsize - 1] != '\0') {
1032 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1033 talloc_free(tmp_ctx);
1036 if (index(script,'/') != NULL) {
1037 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script));
1038 talloc_free(tmp_ctx);
1043 if (stat(ctdb->event_script_dir, &st) != 0 &&
1045 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1046 talloc_free(tmp_ctx);
1051 filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1052 if (filename == NULL) {
1053 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1054 talloc_free(tmp_ctx);
1058 if (stat(filename, &st) != 0) {
1059 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename));
1060 talloc_free(tmp_ctx);
1064 if (chmod(filename, st.st_mode | S_IXUSR) == -1) {
1065 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename));
1066 talloc_free(tmp_ctx);
1070 talloc_free(tmp_ctx);
1074 int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata)
1079 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1081 script = (char *)indata.dptr;
1082 if (indata.dsize == 0) {
1083 DEBUG(DEBUG_ERR,(__location__ " No script specified.\n"));
1084 talloc_free(tmp_ctx);
1087 if (indata.dptr[indata.dsize - 1] != '\0') {
1088 DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n"));
1089 talloc_free(tmp_ctx);
1092 if (index(script,'/') != NULL) {
1093 DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script));
1094 talloc_free(tmp_ctx);
1099 if (stat(ctdb->event_script_dir, &st) != 0 &&
1101 DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir));
1102 talloc_free(tmp_ctx);
1107 filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script);
1108 if (filename == NULL) {
1109 DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n"));
1110 talloc_free(tmp_ctx);
1114 if (stat(filename, &st) != 0) {
1115 DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename));
1116 talloc_free(tmp_ctx);
1120 if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) {
1121 DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename));
1122 talloc_free(tmp_ctx);
1126 talloc_free(tmp_ctx);