1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

eventscript: introduce enum for different event script calls.

Rather than doing strcmp everywhere, pass an explicit enum around.  This
also subtly documents what options are available.  The "options" arg
is now used for extra arguments only.

Unfortunately, gcc complains on empty format strings, so we make
ctdb_event_script() take no varargs, and add ctdb_event_script_args().  We
leave ctdb_event_script_callback() taking varargs, which means callers
have to do "%s", "".

For the moment, we have CTDB_EVENT_UNKNOWN for handling forced scripts
from the ctdb tool.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


(This used to be ctdb commit 8001488be4f2beb25e943fe01b2afc2e8779930d)
This commit is contained in:
Rusty Russell 2009-11-24 11:16:49 +10:30
parent 2763df22de
commit 2d9254404d
7 changed files with 65 additions and 23 deletions

View File

@ -858,6 +858,19 @@ enum ctdb_trans2_commit_error {
CTDB_TRANS2_COMMIT_SOMEFAIL=3 /* some nodes failed the commit, some allowed it */
};
/* different calls to event scripts. */
enum ctdb_eventscript_call {
CTDB_EVENT_STARTUP, /* CTDB starting up: no args. */
CTDB_EVENT_START_RECOVERY, /* CTDB recovery starting: no args. */
CTDB_EVENT_RECOVERED, /* CTDB recovery finished: no args. */
CTDB_EVENT_TAKE_IP, /* IP taken: interface, IP address, netmask bits. */
CTDB_EVENT_RELEASE_IP, /* IP released: interface, IP address, netmask bits. */
CTDB_EVENT_STOPPED, /* This node is stopped: no args. */
CTDB_EVENT_MONITOR, /* Please check if service is healthy: no args. */
CTDB_EVENT_STATUS, /* Report service status: no args. */
CTDB_EVENT_SHUTDOWN, /* CTDB shutting down: no args. */
CTDB_EVENT_UNKNOWN, /* Other: manually invoked from "ctdb eventscript". */
};
/* internal prototypes */
void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
@ -1326,12 +1339,15 @@ int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata);
void ctdb_takeover_client_destructor_hook(struct ctdb_client *client);
int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
int ctdb_event_script(struct ctdb_context *ctdb, enum ctdb_eventscript_call call);
int ctdb_event_script_args(struct ctdb_context *ctdb, enum ctdb_eventscript_call call,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
int ctdb_event_script_callback(struct ctdb_context *ctdb,
TALLOC_CTX *mem_ctx,
void (*callback)(struct ctdb_context *, int, void *),
void *private_data,
const char *fmt, ...) PRINTF_ATTRIBUTE(5,6);
enum ctdb_eventscript_call call,
const char *fmt, ...) PRINTF_ATTRIBUTE(6,7);
void ctdb_release_all_ips(struct ctdb_context *ctdb);
void set_nonblocking(int fd);

View File

@ -286,7 +286,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
if (ctdb->methods != NULL) {
ctdb->methods->shutdown(ctdb);
}
ctdb_event_script(ctdb, "shutdown");
ctdb_event_script(ctdb, CTDB_EVENT_SHUTDOWN);
DEBUG(DEBUG_NOTICE,("Received SHUTDOWN command. Stopping CTDB daemon.\n"));
exit(0);

View File

@ -224,7 +224,7 @@ static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
if (!ctdb->done_startup) {
ret = ctdb_event_script_callback(ctdb,
ctdb->monitor->monitor_context, ctdb_startup_callback,
ctdb, "startup");
ctdb, CTDB_EVENT_STARTUP, "%s", "");
} else {
int i;
int skip_monitoring = 0;
@ -248,7 +248,7 @@ static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
} else {
ret = ctdb_event_script_callback(ctdb,
ctdb->monitor->monitor_context, ctdb_health_callback,
ctdb, "monitor");
ctdb, CTDB_EVENT_MONITOR, "%s", "");
}
}

View File

@ -964,7 +964,7 @@ int32_t ctdb_control_end_recovery(struct ctdb_context *ctdb,
ret = ctdb_event_script_callback(ctdb, state,
ctdb_end_recovery_callback,
state, "recovered");
state, CTDB_EVENT_RECOVERED, "%s", "");
if (ret != 0) {
ctdb_enable_monitoring(ctdb);
@ -1016,7 +1016,8 @@ int32_t ctdb_control_start_recovery(struct ctdb_context *ctdb,
ret = ctdb_event_script_callback(ctdb, state,
ctdb_start_recovery_callback,
state, "startrecovery");
state, CTDB_EVENT_START_RECOVERY,
"%s", "");
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to start recovery\n"));
@ -1156,7 +1157,7 @@ static void ctdb_recd_ping_timeout(struct event_context *ev, struct timed_event
if (ctdb->methods != NULL) {
ctdb->methods->shutdown(ctdb);
}
ctdb_event_script(ctdb, "shutdown");
ctdb_event_script(ctdb, CTDB_EVENT_SHUTDOWN);
DEBUG(DEBUG_ERR, ("Recovery daemon ping timeout. Daemon has been shut down.\n"));
exit(0);
}
@ -1228,7 +1229,7 @@ int32_t ctdb_control_stop_node(struct ctdb_context *ctdb, struct ctdb_req_contro
ret = ctdb_event_script_callback(ctdb, state,
ctdb_stop_node_callback,
state, "stopped");
state, CTDB_EVENT_STOPPED, "%s", "");
if (ret != 0) {
ctdb_enable_monitoring(ctdb);

View File

@ -3288,7 +3288,7 @@ static void ctdb_check_recd(struct event_context *ev, struct timed_event *te,
if (ctdb->methods != NULL) {
ctdb->methods->shutdown(ctdb);
}
ctdb_event_script(ctdb, "shutdown");
ctdb_event_script(ctdb, CTDB_EVENT_SHUTDOWN);
exit(10);
}

View File

@ -236,7 +236,8 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
ret = ctdb_event_script_callback(ctdb,
state, takeover_ip_callback, state,
"takeip %s %s %u",
CTDB_EVENT_TAKE_IP,
"%s %s %u",
vnn->iface,
talloc_strdup(state, ctdb_addr_to_str(&pip->addr)),
vnn->public_netmask_bits);
@ -391,7 +392,8 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
ret = ctdb_event_script_callback(ctdb,
state, release_ip_callback, state,
"releaseip %s %s %u",
CTDB_EVENT_RELEASE_IP,
"%s %s %u",
vnn->iface,
talloc_strdup(state, ctdb_addr_to_str(&pip->addr)),
vnn->public_netmask_bits);
@ -1352,7 +1354,7 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb)
if (vnn->pnn == ctdb->pnn) {
vnn->pnn = -1;
}
ctdb_event_script(ctdb, "releaseip %s %s %u",
ctdb_event_script_args(ctdb, CTDB_EVENT_RELEASE_IP, "%s %s %u",
vnn->iface,
talloc_strdup(ctdb, ctdb_addr_to_str(&vnn->public_address)),
vnn->public_netmask_bits);
@ -2093,7 +2095,8 @@ int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA inda
ret = ctdb_event_script_callback(ctdb,
mem_ctx, delete_ip_callback, mem_ctx,
"releaseip %s %s %u",
CTDB_EVENT_RELEASE_IP,
"%s %s %u",
vnn->iface,
talloc_strdup(mem_ctx, ctdb_addr_to_str(&vnn->public_address)),
vnn->public_netmask_bits);

View File

@ -32,6 +32,19 @@ static struct {
const char *script_running;
} child_state;
static const char *call_names[] = {
"startup",
"startrecovery",
"recovered",
"takeip",
"releaseip",
"stopped",
"monitor",
"status",
"shutdown",
""
};
static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p);
/*
@ -737,13 +750,14 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
void (*callback)(struct ctdb_context *, int, void *),
void *private_data,
enum ctdb_eventscript_call call,
const char *fmt, va_list ap)
{
TALLOC_CTX *mem_ctx;
struct ctdb_event_script_state *state;
int ret;
if (!strcmp(fmt, "monitor") || !strcmp(fmt, "status")) {
if (call == CTDB_EVENT_MONITOR || call == CTDB_EVENT_STATUS) {
/* if this was a "monitor" or a status event, we recycle the
context to start a new monitor event
*/
@ -781,7 +795,9 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
state->ctdb = ctdb;
state->callback = callback;
state->private_data = private_data;
state->options = talloc_vasprintf(state, fmt, ap);
state->options = talloc_asprintf(state, "%s ", call_names[call]);
if (state->options)
state->options = talloc_vasprintf_append(discard_const_p(char, state->options), fmt, ap);
state->timeout = timeval_set(ctdb->tunable.script_timeout, 0);
if (state->options == NULL) {
DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
@ -847,13 +863,14 @@ int ctdb_event_script_callback(struct ctdb_context *ctdb,
TALLOC_CTX *mem_ctx,
void (*callback)(struct ctdb_context *, int, void *),
void *private_data,
enum ctdb_eventscript_call call,
const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = ctdb_event_script_callback_v(ctdb, callback, private_data, fmt, ap);
ret = ctdb_event_script_callback_v(ctdb, callback, private_data, call, fmt, ap);
va_end(ap);
return ret;
@ -879,20 +896,20 @@ static void event_script_callback(struct ctdb_context *ctdb, int status, void *p
run the event script, waiting for it to complete. Used when the caller
doesn't want to continue till the event script has finished.
*/
int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
int ctdb_event_script_args(struct ctdb_context *ctdb, enum ctdb_eventscript_call call,
const char *fmt, ...)
{
va_list ap;
int ret;
struct callback_status status;
va_start(ap, fmt);
ret = ctdb_event_script_callback_v(ctdb,
event_script_callback, &status, fmt, ap);
va_end(ap);
ret = ctdb_event_script_callback_v(ctdb,
event_script_callback, &status, call, fmt, ap);
if (ret != 0) {
return ret;
}
va_end(ap);
status.status = -1;
status.done = false;
@ -902,6 +919,11 @@ int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
return status.status;
}
int ctdb_event_script(struct ctdb_context *ctdb, enum ctdb_eventscript_call call)
{
/* GCC complains about empty format string, so use %s and "". */
return ctdb_event_script_args(ctdb, call, "%s", "");
}
struct eventscript_callback_state {
struct ctdb_req_control *c;
@ -955,7 +977,7 @@ int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
ret = ctdb_event_script_callback(ctdb,
state, run_eventscripts_callback, state,
"%s", (const char *)indata.dptr);
CTDB_EVENT_UNKNOWN, "%s", (const char *)indata.dptr);
if (ret != 0) {
ctdb_enable_monitoring(ctdb);