diff options
| author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2009-08-13 13:04:08 +1000 |
|---|---|---|
| committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2009-08-13 13:04:08 +1000 |
| commit | 1cc79905adaf15ccf5092d27af1c3827e3c7f176 (patch) | |
| tree | 8d89b8dfa8d1ee4f09c9aedb2ec0d61818d41b3d /ctdb | |
| parent | 8f393eb987ac34020ce116f6b4a2bb3f6f84238a (diff) | |
| download | samba-1cc79905adaf15ccf5092d27af1c3827e3c7f176.tar.gz samba-1cc79905adaf15ccf5092d27af1c3827e3c7f176.tar.xz samba-1cc79905adaf15ccf5092d27af1c3827e3c7f176.zip | |
add new controls to make it possible to enable/disable individual eventscripts
update scriptstatus output so it lists disabled scripts
(This used to be ctdb commit 7e799b7523c9699bd65a8a8207f7e03d668b0b81)
Diffstat (limited to 'ctdb')
| -rw-r--r-- | ctdb/client/ctdb_client.c | 66 | ||||
| -rw-r--r-- | ctdb/include/ctdb.h | 4 | ||||
| -rw-r--r-- | ctdb/include/ctdb_private.h | 8 | ||||
| -rw-r--r-- | ctdb/server/ctdb_control.c | 9 | ||||
| -rw-r--r-- | ctdb/server/eventscript.c | 382 | ||||
| -rw-r--r-- | ctdb/tools/ctdb.c | 49 |
6 files changed, 440 insertions, 78 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c index 2e7a0936ff..a6135c9052 100644 --- a/ctdb/client/ctdb_client.c +++ b/ctdb/client/ctdb_client.c @@ -3568,6 +3568,27 @@ int ctdb_ctrl_event_script_stop(struct ctdb_context *ctdb, int32_t result) return 0; } +/* + tell the main daemon a script was disabled + */ +int ctdb_ctrl_event_script_disabled(struct ctdb_context *ctdb, const char *name) +{ + int ret; + int32_t res; + TDB_DATA data; + + data.dptr = discard_const(name); + data.dsize = strlen(name)+1; + + ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_DISABLED, 0, data, + ctdb, NULL, &res, NULL, NULL); + if (ret != 0 || res != 0) { + DEBUG(DEBUG_ERR,("Failed to send event_script_disabeld\n")); + return -1; + } + + return 0; +} /* get the status of running the monitor eventscripts @@ -3776,3 +3797,48 @@ int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout return 0; } + +/* enable an eventscript + */ +int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script) +{ + int ret; + TDB_DATA data; + int32_t res; + + data.dsize = strlen(script) + 1; + data.dptr = discard_const(script); + + ret = ctdb_control(ctdb, destnode, 0, + CTDB_CONTROL_ENABLE_SCRIPT, 0, data, + NULL, NULL, &res, &timeout, NULL); + if (ret != 0 || res != 0) { + DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n")); + return -1; + } + + return 0; +} + +/* disable an eventscript + */ +int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script) +{ + int ret; + TDB_DATA data; + int32_t res; + + data.dsize = strlen(script) + 1; + data.dptr = discard_const(script); + + ret = ctdb_control(ctdb, destnode, 0, + CTDB_CONTROL_DISABLE_SCRIPT, 0, data, + NULL, NULL, &res, &timeout, NULL); + if (ret != 0 || res != 0) { + DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n")); + return -1; + } + + return 0; +} + diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index a5d6639d6b..f6773598dc 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -634,6 +634,7 @@ struct ctdb_monitoring_script_wire { char name[MAX_SCRIPT_NAME+1]; struct timeval start; struct timeval finished; + int32_t disabled; int32_t status; int32_t timedout; char output[MAX_SCRIPT_OUTPUT+1]; @@ -665,4 +666,7 @@ int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, u int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole); int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole); +int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script); +int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script); + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 63e3d3889b..0660dc8851 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -584,6 +584,9 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0, CTDB_CONTROL_SET_NATGWSTATE = 103, CTDB_CONTROL_SET_LMASTERROLE = 104, CTDB_CONTROL_SET_RECMASTERROLE = 105, + CTDB_CONTROL_EVENT_SCRIPT_DISABLED = 106, + CTDB_CONTROL_ENABLE_SCRIPT = 107, + CTDB_CONTROL_DISABLE_SCRIPT = 108, }; /* @@ -1444,10 +1447,12 @@ int ctdb_ctrl_event_script_init(struct ctdb_context *ctdb); int ctdb_ctrl_event_script_start(struct ctdb_context *ctdb, const char *name); int ctdb_ctrl_event_script_stop(struct ctdb_context *ctdb, int32_t res); int ctdb_ctrl_event_script_finished(struct ctdb_context *ctdb); +int ctdb_ctrl_event_script_disabled(struct ctdb_context *ctdb, const char *name); int32_t ctdb_control_event_script_init(struct ctdb_context *ctdb); int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA indata); int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indata); +int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA indata); int32_t ctdb_control_event_script_finished(struct ctdb_context *ctdb); @@ -1461,4 +1466,7 @@ int32_t ctdb_control_continue_node(struct ctdb_context *ctdb); int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db); +int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata); +int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata); + #endif diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c index e43089ce93..7798d526ac 100644 --- a/ctdb/server/ctdb_control.c +++ b/ctdb/server/ctdb_control.c @@ -437,6 +437,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, CHECK_CONTROL_DATA_SIZE(0); return ctdb_control_event_script_finished(ctdb); + case CTDB_CONTROL_EVENT_SCRIPT_DISABLED: + return ctdb_control_event_script_disabled(ctdb, indata); + case CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS: CHECK_CONTROL_DATA_SIZE(0); return ctdb_control_get_event_script_status(ctdb, outdata); @@ -509,6 +512,12 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, return 0; } + case CTDB_CONTROL_ENABLE_SCRIPT: + return ctdb_control_enable_script(ctdb, indata); + + case CTDB_CONTROL_DISABLE_SCRIPT: + return ctdb_control_disable_script(ctdb, indata); + default: DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode)); return -1; diff --git a/ctdb/server/eventscript.c b/ctdb/server/eventscript.c index 9ea2e120e4..fc933528e8 100644 --- a/ctdb/server/eventscript.c +++ b/ctdb/server/eventscript.c @@ -58,6 +58,7 @@ struct ctdb_monitor_script_status { const char *name; struct timeval start; struct timeval finished; + int32_t disabled; int32_t status; int32_t timedout; char *output; @@ -188,6 +189,36 @@ int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indat return 0; } +/* called from the event script child process when we have a disabled script + */ +int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA indata) +{ + int32_t res = *((int32_t *)indata.dptr); + struct ctdb_monitoring_status *monitoring_status = + talloc_get_type(ctdb->script_monitoring_ctx, + struct ctdb_monitoring_status); + struct ctdb_monitor_script_status *script; + + DEBUG(DEBUG_INFO, ("event script disabed called : %d\n", (int)res)); + + if (monitoring_status == NULL) { + DEBUG(DEBUG_ERR,(__location__ " script_status is NULL when script finished.\n")); + return -1; + } + + script = monitoring_status->scripts; + if (script == NULL) { + DEBUG(DEBUG_ERR,(__location__ " script is NULL when the script had finished\n")); + return -1; + } + + script->finished = timeval_current(); + script->status = res; + script->disabled = 1; + + return 0; +} + /* called from the event script child process when we have completed a * monitor event */ @@ -232,6 +263,7 @@ static struct ctdb_monitoring_wire *marshall_monitoring_scripts(TALLOC_CTX *mem_ strncpy(script_wire.name, script->name, MAX_SCRIPT_NAME); script_wire.start = script->start; script_wire.finished = script->finished; + script_wire.disabled = script->disabled; script_wire.status = script->status; script_wire.timedout = script->timedout; if (script->output != NULL) { @@ -282,73 +314,27 @@ int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb, TDB_DATA return 0; } -/* - run the event script - varargs version - this function is called and run in the context of a forked child - which allows it to do blocking calls such as system() - */ -static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) +struct ctdb_script_tree_item { + const char *name; + int32_t is_enabled; +}; + +struct ctdb_script_list { + struct ctdb_script_list *next; + const char *name; + int32_t is_enabled; +}; + +static struct ctdb_script_list *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx) { - char *cmdstr; - int ret; - struct stat st; - TALLOC_CTX *tmp_ctx = talloc_new(ctdb); - trbt_tree_t *tree; DIR *dir; struct dirent *de; - char *script; + struct stat st; + trbt_tree_t *tree; + struct ctdb_script_list *head, *tail, *new_item; + TALLOC_CTX *tmp_ctx = talloc_new(ctdb); + struct ctdb_script_tree_item *tree_item; int count; - int is_monitor = 0; - char *d_name_dup; - - if (!strcmp(options, "monitor")) { - is_monitor = 1; - } - - if (is_monitor == 1) { - /* This is running in the forked child process. At this stage - * we want to switch from being a ctdb daemon into being a - * client and connect to the real local daemon. - */ - if (switch_from_server_to_client(ctdb) != 0) { - DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch eventscript child into client mode. shutting down.\n")); - _exit(1); - } - - if (ctdb_ctrl_event_script_init(ctdb) != 0) { - DEBUG(DEBUG_ERR,(__location__ " Failed to init event script monitoring\n")); - talloc_free(tmp_ctx); - return -1; - } - } - - if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) { - /* we guarantee that only some specifically allowed event scripts are run - while in recovery */ - const char *allowed_scripts[] = {"startrecovery", "shutdown", "releaseip", "stopped" }; - int i; - for (i=0;i<ARRAY_SIZE(allowed_scripts);i++) { - if (strncmp(options, allowed_scripts[i], strlen(allowed_scripts[i])) == 0) break; - } - if (i == ARRAY_SIZE(allowed_scripts)) { - DEBUG(DEBUG_ERR,("Refusing to run event scripts with option '%s' while in recovery\n", - options)); - talloc_free(tmp_ctx); - return -1; - } - } - - if (setpgid(0,0) != 0) { - DEBUG(DEBUG_ERR,("Failed to create process group for event scripts - %s\n", - strerror(errno))); - talloc_free(tmp_ctx); - return -1; - } - - signal(SIGTERM, sigterm); - - child_state.start = timeval_current(); - child_state.script_running = "startup"; /* the service specific event scripts @@ -357,7 +343,7 @@ static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) errno == ENOENT) { DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir)); talloc_free(tmp_ctx); - return -1; + return NULL; } /* create a tree to store all the script names in */ @@ -370,7 +356,7 @@ static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) if (dir == NULL) { DEBUG(DEBUG_CRIT,("Failed to open event script directory '%s'\n", ctdb->event_script_dir)); talloc_free(tmp_ctx); - return -1; + return NULL; } count = 0; @@ -404,26 +390,145 @@ static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) DEBUG(DEBUG_ERR,("Could not stat event script %s. Ignoring this event script\n", str)); continue; } + + + tree_item = talloc(tree, struct ctdb_script_tree_item); + if (tree_item == NULL) { + DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new tree item\n")); + talloc_free(tmp_ctx); + return NULL; + } + + tree_item->is_enabled = 1; if (!(st.st_mode & S_IXUSR)) { DEBUG(DEBUG_INFO,("Event script %s is not executable. Ignoring this event script\n", str)); - continue; + tree_item->is_enabled = 0; } - - + + tree_item->name = talloc_strdup(tree_item, de->d_name); + if (tree_item->name == NULL) { + DEBUG(DEBUG_ERR,(__location__ " Failed to allocate script name.\n")); + talloc_free(tmp_ctx); + return NULL; + } + /* store the event script in the tree */ - d_name_dup = talloc_strdup(tree, de->d_name); - CTDB_NO_MEMORY(ctdb, d_name_dup); - trbt_insert32(tree, (num<<16)|count++, d_name_dup); + trbt_insert32(tree, (num<<16)|count++, tree_item); } closedir(dir); + + head = NULL; + tail = NULL; + + /* fetch the scripts from the tree one by one and add them to the linked + list + */ + while ((tree_item=trbt_findfirstarray32(tree, 1)) != NULL) { + + new_item = talloc(tmp_ctx, struct ctdb_script_list); + if (new_item == NULL) { + DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new list item\n")); + talloc_free(tmp_ctx); + return NULL; + } + + new_item->next = NULL; + new_item->name = talloc_steal(new_item, tree_item->name); + new_item->is_enabled = tree_item->is_enabled; + + if (head == NULL) { + head = new_item; + tail = new_item; + } else { + tail->next = new_item; + tail = new_item; + } + + talloc_steal(mem_ctx, new_item); + + /* remove this script from the tree */ + talloc_free(tree_item); + } + + talloc_free(tmp_ctx); + return head; +} + + + +/* + run the event script - varargs version + this function is called and run in the context of a forked child + which allows it to do blocking calls such as system() + */ +static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) +{ + char *cmdstr; + int ret; + TALLOC_CTX *tmp_ctx = talloc_new(ctdb); + struct ctdb_script_list *scripts, *current; + int is_monitor = 0; + + if (!strcmp(options, "monitor")) { + is_monitor = 1; + } + + if (is_monitor == 1) { + /* This is running in the forked child process. At this stage + * we want to switch from being a ctdb daemon into being a + * client and connect to the real local daemon. + */ + if (switch_from_server_to_client(ctdb) != 0) { + DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch eventscript child into client mode. shutting down.\n")); + _exit(1); + } + + if (ctdb_ctrl_event_script_init(ctdb) != 0) { + DEBUG(DEBUG_ERR,(__location__ " Failed to init event script monitoring\n")); + talloc_free(tmp_ctx); + return -1; + } + } + + if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) { + /* we guarantee that only some specifically allowed event scripts are run + while in recovery */ + const char *allowed_scripts[] = {"startrecovery", "shutdown", "releaseip", "stopped" }; + int i; + for (i=0;i<ARRAY_SIZE(allowed_scripts);i++) { + if (strncmp(options, allowed_scripts[i], strlen(allowed_scripts[i])) == 0) break; + } + if (i == ARRAY_SIZE(allowed_scripts)) { + DEBUG(DEBUG_ERR,("Refusing to run event scripts with option '%s' while in recovery\n", + options)); + talloc_free(tmp_ctx); + return -1; + } + } + + if (setpgid(0,0) != 0) { + DEBUG(DEBUG_ERR,("Failed to create process group for event scripts - %s\n", + strerror(errno))); + talloc_free(tmp_ctx); + return -1; + } + + signal(SIGTERM, sigterm); + + child_state.start = timeval_current(); + child_state.script_running = "startup"; + + scripts = ctdb_get_script_list(ctdb, tmp_ctx); + /* fetch the scripts from the tree one by one and execute them */ - while ((script=trbt_findfirstarray32(tree, 1)) != NULL) { + for (current=scripts; current; current=current->next) { + /* we dont run disabled scripts, we just report they are disabled */ cmdstr = talloc_asprintf(tmp_ctx, "%s/%s %s", ctdb->event_script_dir, - script, options); + current->name, options); CTDB_NO_MEMORY(ctdb, cmdstr); DEBUG(DEBUG_INFO,("Executing event script %s\n",cmdstr)); @@ -432,11 +537,24 @@ static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) child_state.script_running = cmdstr; if (is_monitor == 1) { - if (ctdb_ctrl_event_script_start(ctdb, script) != 0) { + if (ctdb_ctrl_event_script_start(ctdb, current->name) != 0) { DEBUG(DEBUG_ERR,(__location__ " Failed to start event script monitoring\n")); talloc_free(tmp_ctx); return -1; } + + if (!current->is_enabled) { + if (ctdb_ctrl_event_script_disabled(ctdb, current->name) != 0) { + DEBUG(DEBUG_ERR,(__location__ " Failed to report disabled eventscript\n")); + talloc_free(tmp_ctx); + return -1; + } + } + + } + + if (!current->is_enabled) { + continue; } ret = system(cmdstr); @@ -468,9 +586,6 @@ static int ctdb_event_script_v(struct ctdb_context *ctdb, const char *options) talloc_free(tmp_ctx); return ret; } - - /* remove this script from the tree */ - talloc_free(script); } child_state.start = timeval_current(); @@ -814,3 +929,116 @@ int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb, return 0; } + + +int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata) +{ + const char *script; + struct stat st; + char *filename; + TALLOC_CTX *tmp_ctx = talloc_new(ctdb); + + script = (char *)indata.dptr; + if (indata.dsize == 0) { + DEBUG(DEBUG_ERR,(__location__ " No script specified.\n")); + talloc_free(tmp_ctx); + return -1; + } + if (indata.dptr[indata.dsize - 1] != '\0') { + DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n")); + talloc_free(tmp_ctx); + return -1; + } + if (index(script,'/') != NULL) { + DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to enable script %s\n", script)); + talloc_free(tmp_ctx); + return -1; + } + + + if (stat(ctdb->event_script_dir, &st) != 0 && + errno == ENOENT) { + DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir)); + talloc_free(tmp_ctx); + return -1; + } + + + filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script); + if (filename == NULL) { + DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n")); + talloc_free(tmp_ctx); + return -1; + } + + if (stat(filename, &st) != 0) { + DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to enable script.\n", filename)); + talloc_free(tmp_ctx); + return -1; + } + + if (chmod(filename, st.st_mode | S_IXUSR) == -1) { + DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to enable script.\n", filename)); + talloc_free(tmp_ctx); + return -1; + } + + talloc_free(tmp_ctx); + return 0; +} + +int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata) +{ + const char *script; + struct stat st; + char *filename; + TALLOC_CTX *tmp_ctx = talloc_new(ctdb); + + script = (char *)indata.dptr; + if (indata.dsize == 0) { + DEBUG(DEBUG_ERR,(__location__ " No script specified.\n")); + talloc_free(tmp_ctx); + return -1; + } + if (indata.dptr[indata.dsize - 1] != '\0') { + DEBUG(DEBUG_ERR,(__location__ " String is not null terminated.\n")); + talloc_free(tmp_ctx); + return -1; + } + if (index(script,'/') != NULL) { + DEBUG(DEBUG_ERR,(__location__ " Script name contains '/'. Failed to disable script %s\n", script)); + talloc_free(tmp_ctx); + return -1; + } + + + if (stat(ctdb->event_script_dir, &st) != 0 && + errno == ENOENT) { + DEBUG(DEBUG_CRIT,("No event script directory found at '%s'\n", ctdb->event_script_dir)); + talloc_free(tmp_ctx); + return -1; + } + + + filename = talloc_asprintf(tmp_ctx, "%s/%s", ctdb->event_script_dir, script); + if (filename == NULL) { + DEBUG(DEBUG_ERR,(__location__ " Failed to create script path\n")); + talloc_free(tmp_ctx); + return -1; + } + + if (stat(filename, &st) != 0) { + DEBUG(DEBUG_ERR,("Could not stat event script %s. Failed to disable script.\n", filename)); + talloc_free(tmp_ctx); + return -1; + } + + if (chmod(filename, st.st_mode & ~(S_IXUSR|S_IXGRP|S_IXOTH)) == -1) { + DEBUG(DEBUG_ERR,("Could not chmod %s. Failed to disable script.\n", filename)); + talloc_free(tmp_ctx); + return -1; + } + + talloc_free(tmp_ctx); + return 0; +} diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 90c7862911..a419e23aca 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -734,6 +734,11 @@ static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char printf("%d scripts were executed last monitoring cycle\n", script_status->num_scripts); for (i=0; i<script_status->num_scripts; i++) { + if (script_status->scripts[i].disabled) { + printf("%-20s Status:DISABLED\n", + script_status->scripts[i].name); + continue; + } printf("%-20s Status:%s ", script_status->scripts[i].name, script_status->scripts[i].timedout?"TIMEDOUT":script_status->scripts[i].status==0?"OK":"ERROR"); @@ -756,6 +761,46 @@ static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char /* + enable an eventscript + */ +static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + if (argc < 1) { + usage(); + } + + ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]); + if (ret != 0) { + DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn)); + return ret; + } + + return 0; +} + +/* + disable an eventscript + */ +static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + if (argc < 1) { + usage(); + } + + ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]); + if (ret != 0) { + DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn)); + return ret; + } + + return 0; +} + +/* display the pnn of the recovery master */ static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv) @@ -3343,7 +3388,9 @@ static const struct { { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"}, { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."}, { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"}, - { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts"}, + { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts"}, + { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"}, + { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"}, { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"}, { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" }, { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"}, |
