ctdb-daemon: Do not run monitor event if any other event is already running
authorAmitay Isaacs <amitay@gmail.com>
Thu, 19 Dec 2013 02:01:25 +0000 (13:01 +1100)
committerMartin Schwenke <martin@meltin.net>
Tue, 21 Jan 2014 00:30:41 +0000 (11:30 +1100)
Any currently running monitor events are cancelled if any other events
are scheduled.  However, this does not stop monitor events to be run
when other events are already running.

Keep track of the number of active events and schedule monitor event
only if there are no active events.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/include/ctdb_private.h
ctdb/server/eventscript.c

index eba4045083f0cb928d4f180af82a65c0cb6fe3e8..b95b2c7b84ff0f52bd1419f9bc6eedca4d23e7cf 100644 (file)
@@ -526,6 +526,7 @@ struct ctdb_context {
        TALLOC_CTX *release_ips_ctx; /* a context used to automatically drop all IPs if we fail to recover the node */
 
        TALLOC_CTX *event_script_ctx;
+       int active_events;
 
        struct ctdb_event_script_state *current_monitor;
        struct ctdb_scripts_wire *last_status[CTDB_EVENT_MAX];
index 0feb32b44c5d404583968e0c374628deb9c1f073..e40405eac5291222e82cf9a4a16f00b6ed90c708 100644 (file)
@@ -645,6 +645,11 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
                status = 0;
        }
 
+       state->ctdb->active_events--;
+       if (state->ctdb->active_events < 0) {
+               ctdb_fatal(state->ctdb, "Active events < 0");
+       }
+
        /* This is allowed to free us; talloc will prevent double free anyway,
         * but beware if you call this outside the destructor!
         * the callback hangs off a different context so we walk the list
@@ -750,6 +755,14 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
                }
        }
 
+       /* Do not run new monitor events if some event is already running */
+       if (call == CTDB_EVENT_MONITOR && ctdb->active_events > 0) {
+               if (callback != NULL) {
+                       callback(ctdb, -ECANCELED, private_data);
+               }
+               return 0;
+       }
+
        /* Kill off any running monitor events to run this event. */
        if (ctdb->current_monitor) {
                struct ctdb_event_script_state *ms = talloc_get_type(ctdb->current_monitor, struct ctdb_event_script_state);
@@ -816,6 +829,8 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
 
        talloc_set_destructor(state, event_script_destructor);
 
+       ctdb->active_events++;
+
        /* Nothing to do? */
        if (state->scripts->num_scripts == 0) {
                talloc_free(state);