From 470822b329f9d3ca9bef518b56e9ce28d5fedda2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 24 Nov 2009 11:16:49 +1030 Subject: [PATCH] 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 --- include/ctdb_private.h | 20 ++++++++++++++++++-- server/ctdb_control.c | 2 +- server/ctdb_monitor.c | 4 ++-- server/ctdb_recover.c | 9 +++++---- server/ctdb_recoverd.c | 2 +- server/ctdb_takeover.c | 11 +++++++---- server/eventscript.c | 40 +++++++++++++++++++++++++++++++--------- 7 files changed, 65 insertions(+), 23 deletions(-) diff --git a/include/ctdb_private.h b/include/ctdb_private.h index 0ba8e351..f8b72d4f 100644 --- a/include/ctdb_private.h +++ b/include/ctdb_private.h @@ -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); diff --git a/server/ctdb_control.c b/server/ctdb_control.c index bf82e515..970e0056 100644 --- a/server/ctdb_control.c +++ b/server/ctdb_control.c @@ -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); diff --git a/server/ctdb_monitor.c b/server/ctdb_monitor.c index 2c97f45a..efb767a3 100644 --- a/server/ctdb_monitor.c +++ b/server/ctdb_monitor.c @@ -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", ""); } } diff --git a/server/ctdb_recover.c b/server/ctdb_recover.c index 1cd4835c..76b0a9b5 100644 --- a/server/ctdb_recover.c +++ b/server/ctdb_recover.c @@ -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); diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c index ecdcd99d..d304e24d 100644 --- a/server/ctdb_recoverd.c +++ b/server/ctdb_recoverd.c @@ -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); } diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c index d53f2d47..6bc4e37a 100644 --- a/server/ctdb_takeover.c +++ b/server/ctdb_takeover.c @@ -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); diff --git a/server/eventscript.c b/server/eventscript.c index c89d402c..ccb19180 100644 --- a/server/eventscript.c +++ b/server/eventscript.c @@ -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 */ @@ -782,7 +796,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")); @@ -848,13 +864,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; @@ -880,20 +897,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; @@ -903,6 +920,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; @@ -956,7 +978,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); -- 2.34.1