ctdb-common: Add support to run events through failure
authorAmitay Isaacs <amitay@gmail.com>
Thu, 17 May 2018 03:32:37 +0000 (13:32 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 5 Jun 2018 20:34:19 +0000 (22:34 +0200)
Usually run_event will stop executing event scripts on first failure.
Optionally it can continue to run events even on failure(s).

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/common/run_event.c
ctdb/common/run_event.h
ctdb/server/ctdb_eventd.c
ctdb/tests/src/run_event_test.c

index 44b0e7e4979c118f54e7d4a10efae418471db0d1..20e5be84dd2d9f2d52dcf00a9ebb7305f159ba3e 100644 (file)
@@ -612,6 +612,7 @@ struct run_event_state {
        const char *event_str;
        const char *arg_str;
        struct timeval timeout;
+       bool continue_on_failure;
 
        struct run_event_script_list *script_list;
        const char **argv;
@@ -632,7 +633,8 @@ struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
                                  struct run_event_context *run_ctx,
                                  const char *event_str,
                                  const char *arg_str,
-                                 struct timeval timeout)
+                                 struct timeval timeout,
+                                 bool continue_on_failure)
 {
        struct tevent_req *req, *current_req;
        struct run_event_state *state;
@@ -656,6 +658,7 @@ struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
                }
        }
        state->timeout = timeout;
+       state->continue_on_failure = continue_on_failure;
        state->cancelled = false;
 
        state->script_list = talloc_zero(state, struct run_event_script_list);
@@ -836,19 +839,22 @@ static void run_event_next_script(struct tevent_req *subreq)
        /* If a script fails, stop running */
        script->summary = run_event_script_status(script);
        if (script->summary != 0 && script->summary != -ENOEXEC) {
-               state->script_list->num_scripts = state->index + 1;
-
-               if (script->summary == -ETIME && pid != -1) {
-                       run_event_debug(req, pid);
-               }
-
                state->script_list->summary = script->summary;
-               D_NOTICE("%s event %s\n", state->event_str,
-                        (script->summary == -ETIME) ? "timed out" : "failed");
 
-               run_event_stop_running(state->run_ctx);
-               tevent_req_done(req);
-               return;
+               if (! state->continue_on_failure) {
+                       state->script_list->num_scripts = state->index + 1;
+
+                       if (script->summary == -ETIME && pid != -1) {
+                               run_event_debug(req, pid);
+                       }
+                       D_NOTICE("%s event %s\n", state->event_str,
+                                (script->summary == -ETIME) ?
+                                 "timed out" :
+                                 "failed");
+                       run_event_stop_running(state->run_ctx);
+                       tevent_req_done(req);
+                       return;
+               }
        }
 
        state->index += 1;
index 361ef56e398a4d824038a7d00ab64f79e213283e..f53bca3c525395a665d2ed0171263c6e2170036b 100644 (file)
@@ -120,6 +120,7 @@ int run_event_script_disable(struct run_event_context *run_ctx,
  * @param[in] event_str The event argument to the script
  * @param[in] arg_str Event arguments to the script
  * @param[in] timeout How long to wait for execution
+ * @param[in] continue_on_failure Whether to continue to run events on failure
  * @return new tevent request, or NULL on failure
  *
  * arg_str contains optional arguments for an event.
@@ -129,7 +130,8 @@ struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
                                  struct run_event_context *run_ctx,
                                  const char *event_str,
                                  const char *arg_str,
-                                 struct timeval timeout);
+                                 struct timeval timeout,
+                                 bool continue_on_failure);
 
 /**
  * @brief Async computation end to run an event
index 586870c05af3b46326b03d95ee088a819dde968b..ce7b078cf7ab14cba44822c74fae4ff5cc1d077a 100644 (file)
@@ -271,7 +271,8 @@ static struct tevent_req *command_run_send(TALLOC_CTX *mem_ctx,
                                eventd_run_context(state->ectx),
                                ctdb_event_to_string(state->event),
                                request->rdata.data.run->arg_str,
-                               tevent_timeval_current_ofs(timeout, 0));
+                               tevent_timeval_current_ofs(timeout, 0),
+                               false);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
index 9baee3d9111562a9cb4757530f1fb5e893267d2a..e58d07a9eaef217d2eb911393a9d80f23bda5f2d 100644 (file)
@@ -76,7 +76,13 @@ static void do_run(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 
        arg_str = compact_args(argv, argc, 5);
 
-       req = run_event_send(mem_ctx, ev, run_ctx, argv[4], arg_str, timeout);
+       req = run_event_send(mem_ctx,
+                            ev,
+                            run_ctx,
+                            argv[4],
+                            arg_str,
+                            timeout,
+                            false);
        if (req == NULL) {
                fprintf(stderr, "run_proc_send() failed\n");
                return;